接上一篇文章:Android实现图片区域裁剪功能
上一篇文章提及了通过调用系统相册或拍照来实现图片的缩放\裁剪。不过这对于笔者项目的要求同样不适合,笔者需要的是通过对手机屏幕整个进行一个截图,并对这个截图进行裁剪 *** 作。
依靠系统功能确实可以实现图片的裁剪,但是不够灵活。这里笔者提供一种较为灵活的做法。
但是这种做法的用户体验没有上篇文章的好,至于使用何种方法,读者应该自己衡量。
同样,我们先看实际效果图。
这里展示的是笔者项目的一小部分(阅读器):
我们点击左下角的剪切按钮
我们通过红色边框的四个角来控制裁剪的大小,移动红色框体来控制裁剪的位置区域。
接下来我们看看源码的实现:
首先点击剪切按钮的时候,我们应该生成一个Bitmap对象,传递给另一个Activty处理
具体做法如下:
cutP.setonClickListener(new VIEw.OnClickListener() { public voID onClick(VIEw v) { //将一些按钮隐藏 cutP.setVisibility(VIEw.INVISIBLE); mtopbarSwitcher.setVisibility(VIEw.INVISIBLE); mPageSlIDer.setVisibility(VIEw.INVISIBLE); back.setVisibility(VIEw.INVISIBLE); mPageNumberVIEw.setVisibility(VIEw.INVISIBLE); VIEw vIEw = MupdfActivity.this.getwindow().getDecorVIEw(); if (false == vIEw.isDrawingCacheEnabled()) { vIEw.setDrawingCacheEnabled(true); } Bitmap bitmap = vIEw.getDrawingCache(); ImageVIEw imgv = new ImageVIEw(MupdfActivity.this); imgv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT-200)); imgv.setimageBitmap(bitmap); backBitmap = bitmap; //传递给另一个Activity进行裁剪 Intent intent = new Intent(); intent.setClass(MupdfActivity.this,CutActivity.class); startActivity(intent); } });
Tips:这里笔者是将这个截取的Bitmap对象传递给另一个Actvity做相关处理,这里如何在Activity之间进行Bitmap传递呢?这里我们简单的运用java语法特性来完成具体做法如下:
我们在ActvityA中有一个public static Bitmap bitmap对象,当ActivityA跳转到B时,我们直接通过ActivityA.bitmap来获取这个对象。
之后就是如何进行裁剪的 *** 作了。 *** 作在另一个Activity中进行。XML配置文件信息如下:
<?xml version="1.0" enCoding="utf-8"?> <relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" > <com.artifex.mupdf.Crop_Canvas androID:ID="@+ID/myCanvas" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:background="#313131" /> <button androID:ID="@+ID/cutCancel" androID:layout_height="wrap_content" androID:layout_wIDth="wrap_content" androID:text="取消" androID:layout_alignParentBottom="true" androID:layout_alignParentleft="true"/> <button androID:ID="@+ID/cutEnsure" androID:layout_height="wrap_content" androID:layout_wIDth="wrap_content" androID:text="确定" androID:layout_alignParentBottom="true" androID:layout_centerInParent="true"/> <button androID:ID="@+ID/topdf" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="Topdf" androID:layout_alignParentBottom="true" androID:layout_alignParentRight="true"/> </relativeLayout>
通过配置文件可以看到我们自定义了一个VIEw(ImageVIEw)其实现如下:
package com.artifex.mupdf; import androID.content.Context; import androID.graphics.Bitmap; import androID.graphics.Canvas; import androID.graphics.color; import androID.graphics.Matrix; import androID.graphics.Paint; import androID.graphics.Rect; import androID.graphics.RectF; import androID.graphics.Bitmap.Config; import androID.graphics.drawable.BitmapDrawable; import androID.util.AttributeSet; import androID.vIEw.MotionEvent; import androID.Widget.ImageVIEw; public class Crop_Canvas extends ImageVIEw { private final static int PRESS_LB = 0;//表示左下角矩形框 private final static int PRESS_LT = 1;//表示左上角矩形框 private final static int PRESS_RB = 2;//表示右下角矩形框 private final static int PRESS_RT = 3;//表示右上角矩形框 private Bitmap bitMap = null; //原始图片 private RectF src = null; //经过比例转换后的裁剪区域 private RectF dst = null; //图片显示区域,也就是drawBitmap函数中的目标dst private RectF ChooseArea = null; //选择区域 private Paint mPaint = null; //画笔 private Matrix matrix = null; //矩阵 private int mx = 0; //存储触笔移动时,之前�?��的触笔的x坐标 private int my = 0; //存储触笔移动时,之前�?��的触笔的y坐标 private boolean touchFlag = false; //触笔是否在屏幕之�? private boolean cutFlag = false; //是否点击了menu上的裁剪按钮 private int recFlag = -1; //用来存储触笔点击了哪个小矩形框(改变选择区域大小的小矩形框) private boolean firstFlag = false; private RectF recLT = null; //左上角的小矩形框 private RectF recRT = null; //右上角的小矩形框 private RectF recLB = null; //左下角的小矩形框 private RectF recRB = null; //右下角的小矩形框 private static final int left_AREA_Alpha = 50 * 255 / 100; private RectF leftRectL = null; private RectF leftRectR = null; private RectF leftRectT = null; private RectF leftRectB = null; private Paint leftAreaPaint = null; public Crop_Canvas(Context context,AttributeSet attrs) { super(context,attrs); this.init(); } public Crop_Canvas(Context context) { super(context); this.init(); } public voID init(){ cutFlag = true; recLT = new RectF(); recLB = new RectF(); recRT = new RectF(); recRB = new RectF(); dst = new RectF(); mPaint = new Paint(); mPaint.setcolor(color.RED); mPaint.setStyle(Paint.Style.stroke); //将画笔的风格改为空心 ChooseArea = new RectF(); this.setPressRecLoc(); src = null; firstFlag = true; //选择框之外的灰色区域,分成四个矩形框 leftAreaPaint = new Paint(); leftAreaPaint.setStyle(Paint.Style.FILL); leftAreaPaint.setAlpha(Crop_Canvas.left_AREA_Alpha); } public voID setBitmap(Bitmap bitmap){ BitmapDrawable bd = new BitmapDrawable(bitmap); src = new RectF(0,bd.getIntrinsicWIDth(),bd.getIntrinsicHeight()); this.bitMap = bitmap.copy(Config.ARGB_8888,true); this.setimageBitmap(bitMap); leftRectB = new RectF(); leftRectL = new RectF(); leftRectR = new RectF(); leftRectT = new RectF(); } public voID imageScale(){ matrix = this.getimageMatrix(); matrix.mapRect(dst,src); int padding = this.getpaddingBottom(); int wIDth = bitMap.getWIDth(); int height = bitMap.getHeight(); //dst.set(dst.left+padding,dst.top+padding,dst.right+padding,dst.bottom+padding); dst.set(dst.left+20,dst.top+20,wIDth-20,height - 40); ChooseArea = new RectF(dst); this.setPressRecLoc(); } public Bitmap getSubsetBitmap(){ float ratioWIDth = bitMap.getWIDth()/(float)(dst.right-dst.left); float ratioHeight = bitMap.getHeight()/(float)(dst.bottom - dst.top); int left = (int)((ChooseArea.left - dst.left) * ratioWIDth); int right = (int)(left + (ChooseArea.right - ChooseArea.left) * ratioWIDth); int top = (int)((ChooseArea.top - dst.top) * ratioHeight); int bottom = (int)(top + (ChooseArea.bottom - ChooseArea.top) * ratioHeight); src = new RectF(left,top,right,bottom); firstFlag = true; set_leftArea_Alpha(); return Bitmap.createBitmap(bitMap,left,right-left,bottom-top); } //获得ChooseArea对象 public RectF getChooseArea(){ return ChooseArea; } public voID moveChooseArea(int move_x,int move_y){ if(ChooseArea.left + move_x >= dst.left && ChooseArea.right + move_x <= dst.right && ChooseArea.top + move_y >= dst.top && ChooseArea.bottom + move_y <= dst.bottom){ ChooseArea.set(ChooseArea.left + move_x,ChooseArea.top+move_y,ChooseArea.right + move_x,ChooseArea.bottom+move_y); }else{ if(ChooseArea.left + move_x < dst.left){ ChooseArea.set(dst.left,ChooseArea.top,ChooseArea.right+dst.left-ChooseArea.left,ChooseArea.bottom); } if(ChooseArea.right + move_x > dst.right){ ChooseArea.set(ChooseArea.left+dst.right-ChooseArea.right,dst.right,ChooseArea.bottom); } if(ChooseArea.top + move_y < dst.top){ ChooseArea.set(ChooseArea.left,dst.top,ChooseArea.right,ChooseArea.bottom+dst.top-ChooseArea.top); } if(ChooseArea.bottom + move_y > dst.bottom){ ChooseArea.set(ChooseArea.left,ChooseArea.top+dst.bottom-ChooseArea.bottom,dst.bottom); } } this.setPressRecLoc(); mPaint.setcolor(color.GREEN); this.invalIDate(); } public boolean ontouchEvent(MotionEvent event){ mPaint.setcolor(color.RED); if(event.getAction() == MotionEvent.ACTION_DOWN && cutFlag){ //System.out.println(event.getX() + "," + event.getY()); mx = (int)event.getX(); my = (int)event.getY(); if(this.judgeLocation(mx,my)){ touchFlag = true; mPaint.setcolor(color.GREEN); this.invalIDate(); return true; }else{ if(this.findpresseddst((int)event.getX(),(int)event.getY())){ touchFlag = true; mPaint.setcolor(color.RED); return true; } } } if(event.getAction() == MotionEvent.ACTION_MOVE && touchFlag){ //判断是否点击了哪个个小矩形框 if(this.isOutOfarea((int)event.getX(),(int)event.getY())){ return true; } //如果选择区域大小跟图像大小一样时,就不能移动 if(ChooseArea.left == dst.left && ChooseArea.top == dst.top && ChooseArea.right == dst.right && ChooseArea.bottom == dst.bottom){ }else{ this.moveChooseArea((int)event.getX() - mx,(int)event.getY() - my); mx = (int)event.getX(); my = (int)event.getY(); } } if(event.getAction() == MotionEvent.ACTION_UP){ recFlag = -1; this.invalIDate(); touchFlag = false; } return super.ontouchEvent(event); } private boolean isOutOfarea(int x,int y){ switch(recFlag){ case Crop_Canvas.PRESS_LB: this.pressLB(x - mx,y - my); break; case Crop_Canvas.PRESS_LT: this.pressLT(x - mx,y - my); break; case Crop_Canvas.PRESS_RB: this.pressRB(x - mx,y - my); break; case Crop_Canvas.PRESS_RT: this.pressRT(x - mx,y - my); break; default:return false; } mx = x; my = y; this.invalIDate(); return true; } public boolean findpresseddst(int x,int y){ boolean returnFlag = false; if(this.isInRect(x,y,recLB)){ recFlag = Crop_Canvas.PRESS_LB; returnFlag = true; }else if(this.isInRect(x,recLT)){ recFlag = Crop_Canvas.PRESS_LT; returnFlag = true; }else if(this.isInRect(x,recRB)){ recFlag = Crop_Canvas.PRESS_RB; returnFlag = true; }else if(this.isInRect(x,recRT)){ recFlag = Crop_Canvas.PRESS_RT; returnFlag = true; } return returnFlag; } public boolean isInRect(int x,int y,RectF rect){ if(x >= rect.left -20 && x <= rect.right + 20 && y > rect.top - 20 && y < rect.bottom + 20){ return true; } return false; } private voID pressLB(int x,int y){ float left = ChooseArea.left + x; float right = ChooseArea.right; float top = ChooseArea.top; float bottom = ChooseArea.bottom + y; if(left <= right - 30 && left >= dst.left && bottom <= dst.bottom && bottom >= top + 30){ ChooseArea.set(left,bottom); }else{ if(left + x < dst.left){ left = dst.left; } if(bottom + y > dst.bottom){ bottom = dst.bottom; } if(ChooseArea.left + x > ChooseArea.right - 30){ left = ChooseArea.right - 30; } if(ChooseArea.bottom + y < ChooseArea.top + 30){ bottom = ChooseArea.top + 30; } ChooseArea.set(left,bottom); } this.setPressRecLoc(); } private voID pressLT(int x,int y){ float left = ChooseArea.left + x; float right = ChooseArea.right; float top = ChooseArea.top + y; float bottom = ChooseArea.bottom; if(left <= right - 30 && left >= dst.left && top <= bottom - 30 && top >= dst.top){ ChooseArea.set(left,bottom); }else{ if(left < dst.left){ left = dst.left; } if(top < dst.top){ top = dst.top; } if(left > right - 30){ left = right - 30; } if(top > bottom - 30){ top = bottom - 30; } ChooseArea.set(left,bottom); } this.setPressRecLoc(); } private voID pressRT(int x,int y){ float left = ChooseArea.left; float right = ChooseArea.right + x; float top = ChooseArea.top + y; float bottom = ChooseArea.bottom; if(right <= dst.right && right >= left + 30 && top <= bottom - 30 && top >= dst.top){ ChooseArea.set(left,bottom); }else{ if(right > dst.right){ right = dst.right; } if(top < dst.top){ top = dst.top; } if(right < left + 30){ right = left + 30; } if(top > bottom - 30){ top = bottom - 30; } ChooseArea.set(left,bottom); } this.setPressRecLoc(); } private voID pressRB(int x,int y){ float left = ChooseArea.left; float right = ChooseArea.right + x; float top = ChooseArea.top; float bottom = ChooseArea.bottom + y; if(right<= dst.right && right >= left + 30 && bottom <= dst.bottom && bottom >= top + 30){ ChooseArea.set(left,bottom); }else{ if(right > dst.right){ right = dst.right; } if(bottom > dst.bottom){ bottom = dst.bottom; } if(right < left + 30){ right = left + 30; } if(bottom < top + 30){ bottom = top + 30; } ChooseArea.set(left,bottom); } this.setPressRecLoc(); } //每次改变选择区域矩形的大小或者移动,各角落上的小矩形也要改变它的Location private voID setPressRecLoc(){ recLT.set(ChooseArea.left-5,ChooseArea.top-5,ChooseArea.left+5,ChooseArea.top+5); recLB.set(ChooseArea.left-5,ChooseArea.bottom-5,ChooseArea.bottom+5); recRT.set(ChooseArea.right-5,ChooseArea.right+5,ChooseArea.top+5); recRB.set(ChooseArea.right-5,ChooseArea.bottom+5); } public boolean judgeLocation(float x,float y){ float start_x = this.getChooseArea().left; float start_y = this.getChooseArea().top; float last_x = this.getChooseArea().right; float last_y = this.getChooseArea().bottom; //System.out.println("chubi:" + x + "," + y); //System.out.println(start_y + "," + last_y); if(x > start_x+10 && x < last_x-10 && y > start_y+10 && y < last_y-10){ return true; } return false; } public voID onDraw(Canvas canvas){ super.onDraw(canvas); if(firstFlag){ this.imageScale(); firstFlag = false; mPaint.setcolor(color.RED); System.out.println("WIDth: " + (dst.right - dst.left)); System.out.println("Height: " + (dst.bottom - dst.top)); System.out.println("WIDth: " + this.getDrawable().getIntrinsicWIDth()); System.out.println("Height: " + this.getDrawable().getIntrinsicHeight()); }else{ set_leftArea_Alpha(); } canvas.drawRect(ChooseArea,mPaint); mPaint.setcolor(color.BLUE); canvas.drawRect(recLT,mPaint); canvas.drawRect(recLB,mPaint); canvas.drawRect(recRT,mPaint); canvas.drawRect(recRB,mPaint); canvas.drawRect(leftRectL,leftAreaPaint); canvas.drawRect(leftRectR,leftAreaPaint); canvas.drawRect(leftRectT,leftAreaPaint); canvas.drawRect(leftRectB,leftAreaPaint); } public voID set_leftArea_Alpha(){ leftRectL.set(dst.left,ChooseArea.left,dst.bottom); leftRectR.set(ChooseArea.right,dst.bottom); leftRectT.set(ChooseArea.left,ChooseArea.top); leftRectB.set(ChooseArea.left,ChooseArea.bottom,dst.bottom); } }
接下来直接看看Activity源码:
package com.artifex.mupdf.cut; import java.io.file; import java.io.fileNotFoundException; import java.io.fileOutputStream; import java.io.IOException; import java.util.ArrayList; import androID.app.Activity; import androID.graphics.Bitmap; import androID.os.Bundle; import androID.vIEw.VIEw; import androID.vIEw.VIEw.OnClickListener; import androID.vIEw.Window; import androID.Widget.button; import com.andorID.shu.love.R; import com.artifex.mupdf.Crop_Canvas; import com.artifex.mupdf.MupdfActivity; public class CutActivity extends Activity { private Crop_Canvas canvas = null; private Bitmap backBitmap; private button cancel; private button ensure; private button topdf; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestwindowFeature(Window.FEATURE_NO_Title); setContentVIEw(R.layout.cut_image); backBitmap = MupdfActivity.backBitmap; init(); cancel = (button) findVIEwByID(R.ID.cutCancel); cancel.setonClickListener(new OnClickListener() { @OverrIDe public voID onClick(VIEw v) { CutActivity.this.finish(); } }); ensure = (button) findVIEwByID(R.ID.cutEnsure); ensure.setonClickListener(new OnClickListener() { @OverrIDe public voID onClick(VIEw v) { //图片保存的路径,之后将之转换为pdf,并以附件的形似发送邮件 file tmp = new file("/sdcard/lovereader/pic"); tmp.mkdirs(); file f = new file("/sdcard/lovereader/pic/" + "testpic" + ".png"); try { f.createNewfile(); } catch (IOException e1) { // Todo auto-generated catch block e1.printstacktrace(); } fileOutputStream fOut = null; try { fOut = new fileOutputStream(f); } catch (fileNotFoundException e) { e.printstacktrace(); } canvas.getSubsetBitmap().compress(Bitmap.CompressFormat.PNG,100,fOut); try { fOut.flush(); } catch (IOException e) { e.printstacktrace(); } try { fOut.close(); } catch (IOException e) { e.printstacktrace(); } } }); topdf = (button)findVIEwByID(R.ID.topdf); topdf.setonClickListener(new OnClickListener() { @OverrIDe public voID onClick(VIEw v) { // Todo auto-generated method stub ArrayList<String> imageUrlList = new ArrayList<String>(); imageUrlList.add("/sdcard/lovereader/pic/" + "testpic" + ".png"); String pdfUrl = "/sdcard/lovereader/tmp/Foreverlove.pdf"; file tmp = new file("/sdcard/lovereader/tmp"); tmp.mkdirs(); file file = pdfManager.pdf(imageUrlList,pdfUrl); try { file.createNewfile(); } catch (IOException e) { // Todo auto-generated catch block e.printstacktrace(); } } }); } private voID init() { canvas = (Crop_Canvas) findVIEwByID(R.ID.myCanvas); Bitmap bitmap = backBitmap; canvas.setBitmap(bitmap); } }
ok,不依靠系统的简单裁剪功能就实现了,这里笔者就不给出源代码下载了,上述代码读者只要自己改改就可以用了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android实现图片的裁剪(不调用系统功能)全部内容,希望文章能够帮你解决Android实现图片的裁剪(不调用系统功能)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)