博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
区域实现Android实现图片的裁剪(不调用系统功能)
阅读量:5047 次
发布时间:2019-06-12

本文共 16474 字,大约阅读时间需要 54 分钟。

首先声明,我是一个菜鸟。一下文章中出现技术误导情况盖不负责

            接上一篇文章:

            上一篇文章提及了通过调用系统相册或拍照来实现图片的缩放\裁剪。不过这对于笔者项目的

         要求一样不适合,笔者需要的是通过对手机屏幕整个停止一个截图,并对这个截图停止裁剪操作。

         依托系统功能确实可以实现图片的裁剪,但是不够灵巧。这里笔者供给一种较为灵巧的做法。

         但是这种做法的用户体验没有上篇文章的好,至于使用何种方法,读者应该自己权衡。

            一样,我们先看现实效果图。

              这里展示的是笔者项目的一小部分(阅读器):

              区域和实现

           我们点击左下角的剪切按钮

              区域和实现

            我们通过红色边框的四个角来控制裁剪的大小,移动红色框体来控制裁剪的位置区域。

             接下来我们看看源码的实现:

             首先点击剪切按钮的时候,我们应该生成一个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配置文件信息如下:  

             通过配置文件可以看到我们自定义了一个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,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, top, 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,ChooseArea.top						,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						,ChooseArea.right,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, y, recLT)){			recFlag = Crop_Canvas.PRESS_LT;			returnFlag = true;		}else if(this.isInRect(x, y, recRB)){			recFlag = Crop_Canvas.PRESS_RB;			returnFlag = true;		}else if(this.isInRect(x, y, 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,top,right,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,top,right,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,top,right,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,top,right,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,top,right,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,top,right,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,top,right,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,top,right,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.left+5, ChooseArea.bottom+5);		recRT.set(ChooseArea.right-5,ChooseArea.top-5 , ChooseArea.right+5, ChooseArea.top+5);		recRB.set(ChooseArea.right-5,ChooseArea.bottom-5 , 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, dst.top, ChooseArea.left, dst.bottom);		leftRectR.set(ChooseArea.right,dst.top,dst.right,dst.bottom);		leftRectT.set(ChooseArea.left, dst.top, ChooseArea.right, ChooseArea.top);		leftRectB.set(ChooseArea.left,ChooseArea.bottom,ChooseArea.right,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
imageUrllist = new ArrayList
(); 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,不依托系统的简略裁剪功能就实现了,这里笔者就不给出源代码下载了,

         上述代码读者只要自己改改就能够用了。

    

文章结束给大家分享下程序员的一些笑话语录: 一个合格的程序员是不会写出 诸如 “摧毁地球” 这样的程序的,他们会写一个函数叫 “摧毁行星”而把地球当一个参数传进去。

转载于:https://www.cnblogs.com/jiangu66/archive/2013/05/15/3080478.html

你可能感兴趣的文章
BZOJ 1531 二进制优化多重背包
查看>>
BZOJ 2324 (有上下界的)费用流
查看>>
python3基础06(随机数的使用)
查看>>
Zookeeper系列(二)特征及应用场景
查看>>
【HTTP】Fiddler(三)- Fiddler命令行和HTTP断点调试
查看>>
Spring Boot使用Druid和监控配置
查看>>
poi 处理空单元格
查看>>
Android 内存泄漏优化总结
查看>>
luogu4849 寻找宝藏 (cdq分治+dp)
查看>>
Spring Cloud微服务笔记(五)Feign
查看>>
C语言键盘按键列表
查看>>
Codeforces Round #374 (Div. 2)
查看>>
oracle数据类型
查看>>
socket
查看>>
Vue中使用key的作用
查看>>
二叉索引树 树状数组
查看>>
日志框架--(一)基础篇
查看>>
Java设计模式之原型模式
查看>>
Spring学习(四)-----Spring Bean引用同xml和不同xml bean的例子
查看>>
哲理故事与管理之道(20)-用危机激励下属
查看>>