从相册,相机拍照,并对图片进行剪裁

这个是之前做的一个demo,在github中能下载到https://github.com/zz7zz7zz/android-cropImage,我是对里面做了修改

效果图如下:




我这个demo只是对github中剪裁的框框样式和一些拉伸区域做了效果


demo的架构如下:



1、主要是对里面的FloatDrawable.java做了修改

package com.open.crop;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;

/**
 * 头像图片选择框的浮层
 * @author Administrator
 *
 */
public class FloatDrawable extends Drawable {
	
	private Context mContext;
	private Drawable mCropPointDrawable;
	//FIXME add
	private Drawable mCropPointDrawableLeft;
	private Drawable mCropPointDrawableRight;
	private Drawable mCropPointDrawableTop;
	private Drawable mCropPointDrawableBottom;
	
	private Paint mLinePaint=new Paint();
	{
	    mLinePaint.setARGB(200, 50, 50, 50);
	    mLinePaint.setStrokeWidth(1F);
	    mLinePaint.setStyle(Paint.Style.STROKE);
	    mLinePaint.setAntiAlias(true);
	    mLinePaint.setColor(Color.WHITE);
	}
	
	public FloatDrawable(Context context) {
		super();
		this.mContext=context;
		init();
	}
	
	private void init()
	{
		mCropPointDrawable=mContext.getResources().getDrawable(R.drawable.clip_point);
		
		mCropPointDrawableLeft=mContext.getResources().getDrawable(R.drawable.common_photo_left_normal);
		mCropPointDrawableRight=mContext.getResources().getDrawable(R.drawable.common_photo_right_normal);
		mCropPointDrawableTop=mContext.getResources().getDrawable(R.drawable.common_photo_top_normal);
		mCropPointDrawableBottom=mContext.getResources().getDrawable(R.drawable.common_photo_bottom_normal);
		
		
	}
	
	public int getCirleWidth()
	{
		return mCropPointDrawableLeft.getIntrinsicWidth();
	}
	
	public int getCirleHeight()
	{
		return mCropPointDrawableLeft.getIntrinsicHeight();
	}

	@Override
	public void draw(Canvas canvas) {
		
		int left=getBounds().left;
		int top=getBounds().top;
		int right=getBounds().right;
		int bottom=getBounds().bottom;
		
		Rect mRect=new Rect(
				left+mCropPointDrawableLeft.getIntrinsicWidth()/2, 
				top+mCropPointDrawableLeft.getIntrinsicHeight()/2, 
				right-mCropPointDrawableLeft.getIntrinsicWidth()/2, 
				bottom-mCropPointDrawableLeft.getIntrinsicHeight()/2);
		//方框
		canvas.drawRect(mRect, mLinePaint);
		
		//左右边 高度的偏移量
		int lx=(bottom - top) / 2 - mCropPointDrawableLeft.getIntrinsicHeight()/2;
		mCropPointDrawableLeft.setBounds(left, top + lx, left+mCropPointDrawableLeft.getIntrinsicWidth(), top +lx+mCropPointDrawableLeft.getIntrinsicHeight());
		mCropPointDrawableLeft.draw(canvas);
		
		mCropPointDrawableRight.setBounds(right-mCropPointDrawableRight.getIntrinsicWidth(), top + lx, right, top+lx+mCropPointDrawableRight.getIntrinsicHeight());
		mCropPointDrawableRight.draw(canvas);
		
		//上
		int tx=(right - left) / 2 - mCropPointDrawableLeft.getIntrinsicWidth() / 2;
		mCropPointDrawableTop.setBounds(left+tx, top , left+tx+mCropPointDrawableTop.getIntrinsicWidth(), top +mCropPointDrawableTop.getIntrinsicHeight());
		mCropPointDrawableTop.draw(canvas);
//		//下
		mCropPointDrawableBottom.setBounds(left + tx, bottom-mCropPointDrawableBottom.getIntrinsicHeight(), left + tx +mCropPointDrawableBottom.getIntrinsicWidth(), bottom);
		mCropPointDrawableBottom.draw(canvas);
		
		
	}

	@Override
	public void setBounds(Rect bounds) {
		super.setBounds(new Rect(
				bounds.left-mCropPointDrawableLeft.getIntrinsicWidth()/2, 
				bounds.top-mCropPointDrawableLeft.getIntrinsicHeight()/2, 
				bounds.right+mCropPointDrawableLeft.getIntrinsicWidth()/2, 
				bounds.bottom+mCropPointDrawableLeft.getIntrinsicHeight()/2));
	}

	@Override
	public void setAlpha(int alpha) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setColorFilter(ColorFilter cf) {
		// TODO Auto-generated method stub

	}

	@Override
	public int getOpacity() {
		// TODO Auto-generated method stub
		return 0;
	}

}


2、然后还有一些拉伸区域做了修改

package com.open.crop;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * 底图不变,浮层缩放
 * @author yanglonghui
 *
 */
public class CropImageView3 extends View {
	
	//单点触摸的时候
	private float oldX=0;
	private float oldY=0;
	
	//状态
	private final int STATUS_Touch_SINGLE=1;//单点
	private final int STATUS_TOUCH_MULTI_START=2;//多点开始
	private final int STATUS_TOUCH_MULTI_TOUCHING=3;//多点拖拽中
	
	private int mStatus=STATUS_Touch_SINGLE;
	
	//默认的裁剪图片宽度与高度
	private final int defaultCropWidth=300;
	private final int defaultCropHeight=300;
	private int cropWidth=defaultCropWidth;
	private int cropHeight=defaultCropHeight;
	
	private final int EDGE_LT=1;//左上
	private final int EDGE_RT=2;//右上
	private final int EDGE_LB=3;//左下
	private final int EDGE_RB=4;//右下
	private final int EDGE_MOVE_IN=5;//里面移动
	private final int EDGE_MOVE_OUT=6;//外面移动
	private final int EDGE_NONE=7;//外面移动
	
	public int currentEdge=EDGE_NONE;
	
	protected float oriRationWH=0;//原始宽高比率
	protected final float maxZoomOut=5.0f;//最大扩大到多少倍
	protected final float minZoomIn=0.333333f;//最小缩小到多少倍
	
	protected Drawable mDrawable;//原图
	protected FloatDrawable mFloatDrawable;//浮层
	protected Rect mDrawableSrc = new Rect();
	protected Rect mDrawableDst = new Rect();
	protected Rect mDrawableFloat = new Rect();//浮层选择框,就是头像选择框
	protected boolean isFrist=true;
	private boolean isTouchInSquare=true;
	
	protected Context mContext;
    
	public CropImageView3(Context context) {
		super(context);
		init(context);
	}

	public CropImageView3(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public CropImageView3(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
			
	}
	
	@SuppressLint("NewApi")
	private void init(Context context)
	{
		this.mContext=context;
		try {  
            if(android.os.Build.VERSION.SDK_INT>=11)  
            {  
            	this.setLayerType(LAYER_TYPE_SOFTWARE, null);  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
		mFloatDrawable=new FloatDrawable(context);//头像选择框
	}

	public void setDrawable(Drawable mDrawable,int cropWidth,int cropHeight)
	{
		this.mDrawable=mDrawable;
		this.cropWidth=cropWidth;
		this.cropHeight=cropHeight;
		this.isFrist=true;
		invalidate();
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		if(event.getPointerCount()>1)
		{
			if(mStatus==STATUS_Touch_SINGLE)
			{
				mStatus=STATUS_TOUCH_MULTI_START;
			}
			else if(mStatus==STATUS_TOUCH_MULTI_START)
			{
				mStatus=STATUS_TOUCH_MULTI_TOUCHING;
			}
		}
		else
		{
			if(mStatus==STATUS_TOUCH_MULTI_START||mStatus==STATUS_TOUCH_MULTI_TOUCHING)
			{
				oldX=event.getX();
				oldY=event.getY();
			}
			
			mStatus=STATUS_Touch_SINGLE;
		}
		
//Log.v("count currentTouch"+currentTouch, "-------");	

		switch(event.getAction())
		{
			case MotionEvent.ACTION_DOWN:
				oldX = event.getX();
				oldY = event.getY();
				currentEdge=getTouchEdge((int)oldX, (int)oldY);
				isTouchInSquare=mDrawableFloat.contains((int)event.getX(), (int)event.getY());
Log.v("currentEdge:"+currentEdge, "-------");
	            break;
	            
			case MotionEvent.ACTION_UP:
				checkBounds();
	            break;
	            
			case MotionEvent.ACTION_POINTER_1_DOWN:
				break;
				
			case MotionEvent.ACTION_POINTER_UP:
				currentEdge=EDGE_NONE;
				break;
	            
			case MotionEvent.ACTION_MOVE:
				if(mStatus==STATUS_TOUCH_MULTI_TOUCHING)
				{
					
				}
				else if(mStatus==STATUS_Touch_SINGLE)
				{
					int dx=(int)(event.getX()-oldX);
					int dy=(int)(event.getY()-oldY);
					
					oldX=event.getX();
					oldY=event.getY();
					
					if(!(dx==0&&dy==0))
					{
						<span style="color:#ff0000;">switch(currentEdge)</span>
						<span style="color:#ff0000;">{
								case EDGE_LT://左
									mDrawableFloat.set(mDrawableFloat.left+dx, mDrawableFloat.top, mDrawableFloat.right, mDrawableFloat.bottom);
									//FIXME 修改
//									mDrawableFloat.set(mDrawableFloat.left+dx, mDrawableFloat.top, mDrawableFloat.right, mDrawableFloat.bottom);
									break;
									
								case EDGE_RT://右
									mDrawableFloat.set(mDrawableFloat.left, mDrawableFloat.top, mDrawableFloat.right+dx, mDrawableFloat.bottom);
									break;
									
								case EDGE_LB://上
									mDrawableFloat.set(mDrawableFloat.left, mDrawableFloat.top+dy, mDrawableFloat.right, mDrawableFloat.bottom);
									break;
									
								case EDGE_RB://下
									mDrawableFloat.set(mDrawableFloat.left, mDrawableFloat.top, mDrawableFloat.right, mDrawableFloat.bottom+dy);
									break;
									
								case EDGE_MOVE_IN:
									if(isTouchInSquare)
									{
										mDrawableFloat.offset((int)dx, (int)dy);
									}
									break;

								case EDGE_MOVE_OUT:
									break;
						}</span>
						mDrawableFloat.sort();
						invalidate();
					}
				}
	            break;
		}
		
		return true;
	}

    public int getTouchEdge(int eventX,int eventY)
    {
    	//左右
    	int lt=(mFloatDrawable.getBounds().bottom-mFloatDrawable.getBounds().top )/2-mFloatDrawable.getCirleHeight()/2;
    	int lb=(mFloatDrawable.getBounds().bottom-mFloatDrawable.getBounds().top )/2+mFloatDrawable.getCirleHeight()/2;
    	
    	//上下
    	int tl=(mFloatDrawable.getBounds().right-mFloatDrawable.getBounds().left)/2 -mFloatDrawable.getCirleWidth()/2;
    	int tr=(mFloatDrawable.getBounds().right-mFloatDrawable.getBounds().left)/2 +mFloatDrawable.getCirleWidth()/2;
    	
    	if(mFloatDrawable.getBounds().left<=eventX&&eventX<(mFloatDrawable.getBounds().left+mFloatDrawable.getCirleWidth())
    			)
    	{
    		return EDGE_LT;//左
    	}
    	else  if((mFloatDrawable.getBounds().right-mFloatDrawable.getCirleWidth())<=eventX&&eventX<mFloatDrawable.getBounds().right
    			)
    	{
    		return EDGE_RT;//右
    	}
    	else  if((mFloatDrawable.getBounds().top-mFloatDrawable.getCirleHeight()/2)<=eventY&&eventY<(mFloatDrawable.getBounds().top+mFloatDrawable.getCirleHeight()/2))
    	{
    		return EDGE_LB;//上
    	}
    	else  if((mFloatDrawable.getBounds().bottom-mFloatDrawable.getCirleHeight())<=eventY&&eventY<(mFloatDrawable.getBounds().bottom))
    	{
    		return EDGE_RB;//下
    	}
    	else if(mFloatDrawable.getBounds().contains(eventX,eventY))
    	{
    		return EDGE_MOVE_IN;//里面移动
    	}
    	return EDGE_MOVE_OUT;
    }
    
	@Override
	protected void onDraw(Canvas canvas) {
//		super.onDraw(canvas);
		if (mDrawable == null) {
            return; // couldn't resolve the URI
        }

        if (mDrawable.getIntrinsicWidth() == 0 || mDrawable.getIntrinsicHeight() == 0) {
            return;     // nothing to draw (empty bounds)
        }
        
        configureBounds();
        
		mDrawable.draw(canvas);
        canvas.save();
        canvas.clipRect(mDrawableFloat, Region.Op.DIFFERENCE);
        canvas.drawColor(Color.parseColor("#a0000000"));
        canvas.restore();
        mFloatDrawable.draw(canvas);
	}
	
	
	protected void configureBounds()
	{
		if(isFrist)
		{
			oriRationWH=((float)mDrawable.getIntrinsicWidth())/((float)mDrawable.getIntrinsicHeight());
			
			final float scale = mContext.getResources().getDisplayMetrics().density;
			int w=Math.min(getWidth(), (int)(mDrawable.getIntrinsicWidth()*scale+0.5f));
			int h=(int) (w/oriRationWH);
			
			int left = (getWidth()-w)/2;
			int top = (getHeight()-h)/2;
			int right=left+w;
			int bottom=top+h;
			
			mDrawableSrc.set(left,top,right,bottom);
			mDrawableDst.set(mDrawableSrc);
			
			int floatWidth=dipTopx(mContext, cropWidth);
			int floatHeight=dipTopx(mContext, cropHeight);
			
			if(floatWidth>getWidth())
			{
				floatWidth=getWidth();
				floatHeight=cropHeight*floatWidth/cropWidth;
			}
			
			if(floatHeight>getHeight())
			{
				floatHeight=getHeight();
				floatWidth=cropWidth*floatHeight/cropHeight;
			}
			
			int floatLeft=(getWidth()-floatWidth)/2;
			int floatTop = (getHeight()-floatHeight)/2;
			mDrawableFloat.set(floatLeft, floatTop,floatLeft+floatWidth, floatTop+floatHeight);
			
	        isFrist=false;
		}
        
		mDrawable.setBounds(mDrawableDst);
		mFloatDrawable.setBounds(mDrawableFloat);
	}
	
	protected void checkBounds()
	{
		int newLeft = mDrawableFloat.left;
		int newTop = mDrawableFloat.top;
		
		boolean isChange=false;
		if(mDrawableFloat.left<getLeft())
		{
			newLeft=getLeft();
			isChange=true;
		}
		
		if(mDrawableFloat.top<getTop())
		{
			newTop=getTop();
			isChange=true;
		}
		
		if(mDrawableFloat.right>getRight())
		{
			newLeft=getRight()-mDrawableFloat.width();
			isChange=true;
		}

		if(mDrawableFloat.bottom>getBottom())
		{
			newTop=getBottom()-mDrawableFloat.height();
			isChange=true;
		}
		
		mDrawableFloat.offsetTo(newLeft, newTop);
		if(isChange)
		{
			invalidate();
		}
	}
	
	public Bitmap getCropImage()
	{
		Bitmap tmpBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.RGB_565);
		Canvas canvas = new Canvas(tmpBitmap);
		mDrawable.draw(canvas);

		Matrix matrix=new Matrix();
		float scale=(float)(mDrawableSrc.width())/(float)(mDrawableDst.width());
		matrix.postScale(scale, scale);
		
	    Bitmap ret = Bitmap.createBitmap(tmpBitmap, mDrawableFloat.left, mDrawableFloat.top, mDrawableFloat.width(), mDrawableFloat.height(), matrix, true);
	    tmpBitmap.recycle();
	    tmpBitmap=null;
	    
		return ret;
	}
    
    public int dipTopx(Context context, float dpValue) {  
        final float scale = context.getResources().getDisplayMetrics().density;  
       return (int) (dpValue * scale + 0.5f);  
    }
}



源码的下载地址:

点击打开链接

如果没有积分需要这个效果的话,可以给我留言


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值