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提取并存储在单例中,在下一个页面再调用。

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

临行之前,面对太多的疑问和不解:为何是一个人?

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

相关文章:

你感兴趣的文章:

标签云: