• 区域实现Android实现图片的裁剪(不调用系统功能)


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

                接上一篇文章:http://blog.csdn.net/kiritor/article/details/8926336

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

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

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

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

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

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

                  区域和实现

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

                  区域和实现

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

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

                 首先点击剪切按钮的时候,我们应该生成一个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,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<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,不依托系统的简略裁剪功能就实现了,这里笔者就不给出源代码下载了,

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

        

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

  • 相关阅读:
    hdu 1258 DFS
    hdu2488 dfs
    poj1915 BFS
    hdu1372 BFS求最短路径长度
    poj3264 线段树
    hdu 2438Turn the corner 三分
    hdu3714 三分
    【转载】单点登陆
    ajax从入门到深入精通
    Web前端技术体系大全搜索
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3080478.html
Copyright © 2020-2023  润新知