欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现bitmap指定区域滑动截取功能

程序员文章站 2023-12-14 12:26:52
突然不知道什么心态,说要做这个,网上找了半天没找到合适的,就自己做了一个。 先上效果图: 透明区域为将要截取的区域,其他阴影部位为舍弃区域 图片...

突然不知道什么心态,说要做这个,网上找了半天没找到合适的,就自己做了一个。

先上效果图:

Android实现bitmap指定区域滑动截取功能

透明区域为将要截取的区域,其他阴影部位为舍弃区域

图片资源我写死储存在了raw中,有需要可以自己写获取bitmap。

界面layout:

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.admin.myapplication.mainactivity">
  <com.admin.myapplication.screenshotview
    android:id="@+id/screenshotview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
  <linearlayout
    android:id="@+id/title"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:background="#000000">
    <textview
      android:layout_width="match_parent"
      android:layout_height="20dp"
      android:layout_gravity="center"
      android:gravity="center"
      android:text="选择要截取区域"/>
  </linearlayout>
  <linearlayout
    android:id="@+id/bottom"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    android:layout_alignparentbottom="true"
    android:background="#000000"
    android:orientation="horizontal">
    <textview
      android:id="@+id/cancel_btn"
      android:text="取消"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:layout_gravity="center_vertical"
      android:gravity="center"/>
    <textview
      android:id="@+id/certain_btn"
      android:text="确定"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:layout_gravity="center_vertical"
      android:gravity="center"/>
    <textview
      android:id="@+id/restart_btn"
      android:text="重试"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:layout_gravity="center_vertical"
      android:gravity="center"/>
  </linearlayout>

</relativelayout>

screenshotview为自定义view用来显示bitmap,以及滑动截图,其中dot类用来储存坐标点的x,y值。

public class screenshotview extends view {
  private dot startdot;
  private dot enddot;
  private bitmap mbitmap;
  private bitmap ocrbitmap;
  private int screenheight;
  private int screenwidth;
  private dot lefttopdot;
  private dot rightbottomdot;
  private paint paintshadow;
  int shadow = 0xaa000000;
  int clear = 0x0000000;


  public screenshotview(context context) {
    super(context);
    startdot = new dot();
    enddot = new dot();
    lefttopdot = new dot();
    rightbottomdot = new dot();
  }

  public screenshotview(context context, @nullable attributeset attrs) {
    super(context, attrs);
    startdot = new dot();
    enddot = new dot();
    lefttopdot = new dot();
    rightbottomdot = new dot();
  }

  public screenshotview(context context, @nullable attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
    startdot = new dot();
    enddot = new dot();
    lefttopdot = new dot();
    rightbottomdot = new dot();
  }

  public void setbitmap(bitmap bitmap, int screenheight, int screenwidth) {
    mbitmap = bitmap;
    this.screenheight = screenheight;
    this.screenwidth = screenwidth;
    changebitmapsize();
    invalidate();
  }

  public void restart(){
    startdot = new dot();
    enddot = new dot();
    lefttopdot = new dot();
    rightbottomdot = new dot();
    invalidate();
  }
  /**
  *将将要显示的bitmap进行变形,使其铺满屏幕
  *
  */
  private void changebitmapsize() {
    int width = mbitmap.getwidth();
    int height = mbitmap.getheight();
    float scalewidth = ((float) screenwidth) / width;
    float scaleheight = ((float) screenheight) / height;
    matrix matrix = new matrix();
    matrix.postscale(scalewidth, scaleheight);
    mbitmap = bitmap.createbitmap(mbitmap, 0, 0, width, height, matrix, true);
  }

  @override
  protected void ondraw(canvas canvas) {
    super.ondraw(canvas);
    getlefttopdot();
    getrightbottomdot();
    drawbitmap(canvas);
    drawarea(canvas);
    drawshadowtop(canvas);
    drawshadowleft(canvas);
    drawshadowright(canvas);
    drawshadowbottom(canvas);
  }

  /**
  *绘制阴影
  *
  */
  private void drawshadowbottom(canvas canvas) {
    paintshadow = new paint();
    paintshadow.setcolor(shadow);
    canvas.drawrect(0, rightbottomdot.gety(), screenwidth, screenheight, paintshadow);
  }

  private void drawshadowright(canvas canvas) {
    paintshadow = new paint();
    paintshadow.setcolor(shadow);
    canvas.drawrect(rightbottomdot.getx(), lefttopdot.gety(), screenwidth, rightbottomdot.gety(), paintshadow);
  }

  private void drawshadowleft(canvas canvas) {
    paintshadow = new paint();
    paintshadow.setcolor(shadow);
    canvas.drawrect(0, lefttopdot.gety(), lefttopdot.getx(), rightbottomdot.gety(), paintshadow);
  }

  private void drawshadowtop(canvas canvas) {
    paintshadow = new paint();
    paintshadow.setcolor(shadow);
    canvas.drawrect(0, 0, screenwidth, lefttopdot.gety(), paintshadow);
  }

  private void drawbitmap(canvas canvas) {
    paint paint = new paint();
    canvas.drawbitmap(mbitmap, 0, 0, paint);
  }

  /**
   * 画出截图区域
   *
   * @param canvas
   */
  private void drawarea(canvas canvas) {
    paint paint = new paint();
    paint.setcolor(clear);
    canvas.drawrect(lefttopdot.getx(), lefttopdot.gety(), rightbottomdot.getx(), rightbottomdot.gety(), paint);
  }


  /**
   * 获取截图区域bitmap
   *
   * @return 截图
   */
  public bitmap getbitmap() {
    if (mbitmap != null) {
      getlefttopdot();
      getrightbottomdot();
      if (getbitmapoutwidth() > 0 && getbitmapoutheight() > 0) {
        if(lefttopdot.gety()<0){
          lefttopdot.sety(0);
        }
        ocrbitmap = bitmap.createbitmap(mbitmap, (int) lefttopdot.getx(), (int) lefttopdot.gety(), getbitmapoutwidth(), getbitmapoutheight());
      }
    }
    return ocrbitmap;
  }

  /**
   * 获取截图区域宽度
   *
   * @return
   */
  private int getoutwidth() {
    return (int) (rightbottomdot.getx() - lefttopdot.getx());
  }

  /**
   * 获取截图区域高度
   *
   * @return
   */
  private int getoutheight() {
    return (int) (rightbottomdot.gety() - lefttopdot.gety());
  }

  private int getbitmapoutwidth() {
    int bitmapoutwidth;
    int scale = getoutwidth() * mbitmap.getwidth();
    bitmapoutwidth = scale / screenwidth;
    return bitmapoutwidth;
  }

  private int getbitmapoutheight() {
    int bitmapoutheight;
    int scale = getoutheight() * mbitmap.getheight();
    bitmapoutheight = scale / screenheight;
    return bitmapoutheight;
  }

  private void getlefttopdot() {
    if (enddot.getx() > startdot.getx()) {
      lefttopdot.setx(startdot.getx());
    } else {
      lefttopdot.setx(enddot.getx());
    }
    if (enddot.gety() > startdot.gety()) {
      lefttopdot.sety(startdot.gety());
    } else {
      lefttopdot.sety(enddot.gety());
    }
  }

  private void getrightbottomdot() {
    if (startdot.getx() > enddot.getx()) {
      rightbottomdot.setx(startdot.getx());
    } else {
      rightbottomdot.setx(enddot.getx());
    }
    if (startdot.gety() > enddot.gety()) {
      rightbottomdot.sety(startdot.gety());
    } else {
      rightbottomdot.sety(enddot.gety());
    }

  }

  public dot getstartdot() {
    return startdot;
  }

  public void setstartdot(dot startdot) {
    this.startdot = startdot;
  }

  public dot getenddot() {
    return enddot;
  }

  public void setenddot(dot enddot) {
    this.enddot = enddot;
  }

}

mainactivity中完成对点击滑动的监控,通过坐标点的方式获得需要绘制的矩形位置和形状。

public class mainactivity extends appcompatactivity implements view.ontouchlistener, view.onclicklistener {
  private screenshotview screenshotview;
  private bitmap bmp;
  private bitmap ocrbitmap;
  private textview certainbtn;
  private textview cancelbtn;
  private textview restartbtn;
  private int screenwidth;
  private int screenheight;

  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    screenshotview = (screenshotview) findviewbyid(r.id.screenshotview);
    cancelbtn = (textview) findviewbyid(r.id.cancel_btn);
    cancelbtn.setonclicklistener(this);
    certainbtn = (textview) findviewbyid(r.id.certain_btn);
    certainbtn.setonclicklistener(this);
    restartbtn = (textview)findviewbyid(r.id.restart_btn);
    restartbtn.setonclicklistener(this);
    displaymetrics dm = new displaymetrics();
    //获取屏幕信息
    getwindowmanager().getdefaultdisplay().getmetrics(dm);
    screenwidth = dm.widthpixels;
    screenheight = dm.heightpixels;
    resources r = this.getresources();
    inputstream is = r.openrawresource(r.raw.bg);
    bitmapdrawable bmpdraw = new bitmapdrawable(is);
    bmp = bmpdraw.getbitmap();
    screenshotview.setbitmap(bmp, screenheight, screenwidth);
    screenshotview.setontouchlistener(this);
  }

  @override
  public boolean ontouch(view view, motionevent motionevent) {
    switch (motionevent.getaction()) {
      case motionevent.action_down:
        screenshotview.setstartdot(new dot(motionevent.getx(), motionevent.gety()));
        break;
      case motionevent.action_move:
        screenshotview.setenddot(new dot(motionevent.getx(), motionevent.gety()));
        screenshotview.setbitmap(bmp, screenheight, screenwidth);
        break;
      case motionevent.action_up:
        ocrbitmap = screenshotview.getbitmap();
        break;
    }
    return true;
  }

  @override
  public void onclick(view view) {
    switch (view.getid()) {
      case r.id.cancel_btn:
        finish();
        break;
      case r.id.certain_btn:
        if (ocrbitmap != null) {
          bitmaputil.getinstance().setimagebitmap(ocrbitmap);
          intent intent = new intent(mainactivity.this, main2activity.class);
          startactivity(intent);
        }else{
          toast.maketext(mainactivity.this,"请选择截取区域",toast.length_short).show();
        }
        break;
      case r.id.restart_btn:
        screenshotview.restart();
        break;
    }
  }

  @override
  protected void onresume() {
    super.onresume();
    screenshotview.restart();
  }

  @override
  protected void onrestart() {
    super.onrestart();
    screenshotview.restart();
  }
}

运用了单例模式用来存储截取出来的bitmap,方便跳转时调用,不需要自己再写类,点击确定后,会将区域中的bitmap提取并存储在单例中,在下一个页面再调用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: