Android实现bitmap指定区域滑动截取功能
程序员文章站
2023-12-14 12:26:52
突然不知道什么心态,说要做这个,网上找了半天没找到合适的,就自己做了一个。
先上效果图:
透明区域为将要截取的区域,其他阴影部位为舍弃区域
图片...
突然不知道什么心态,说要做这个,网上找了半天没找到合适的,就自己做了一个。
先上效果图:
透明区域为将要截取的区域,其他阴影部位为舍弃区域
图片资源我写死储存在了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提取并存储在单例中,在下一个页面再调用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。