Android 自定义控件之图片裁剪

package view;

import java.util.ArrayList;
import java.util.List;

import util.SystemUtil;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.example.cropimageview.R;

public final class ViewfinderView extends View {

    private Paint paint;
    private Paint tipPaint;

    private Rect frame;// 保存透明窗的边界
    private int frameWidth;// 保存透明窗的宽
    private int frameHeight;// 保存透明窗的高

    private Rect bitmapRect;// 保存bitmap的边界

    private int width;// 屏幕宽
    private int height;// 屏幕高

    private Bitmap bitmap;// 需要截取的图片
    private int bitmapWidth;// 图片的宽
    private int bitmapHeight;// 图片的高

    private int downX;// 按下时的x
    private int downY;// 按下时的y

    private boolean touchInFrame = false;// 触摸是否发生在透明窗
    private boolean touchFrameLeft = false;// 是否触摸左边界
    private boolean touchFrameTop = false;// 是否触摸上边界
    private boolean touchFrameRight = false;// 是否触摸右边界
    private boolean touchFrameBottom = false;// 是否触摸下边界

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

    private void init(Context context) {

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(getResources().getColor(R.color.viewfinder_mask));
        tipPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        tipPaint.setAntiAlias(true);
        tipPaint.setStyle(Style.FILL);
        tipPaint.setColor(Color.WHITE);

        frame = new Rect();
        bitmapRect = new Rect();

        width = SystemUtil.getScreenSize(context)[0];
        height = SystemUtil.getScreenSize(context)[1];

    }

    @Override
    public void onDraw(Canvas canvas) {
        if (bitmap != null) {

            // 画阴影
            canvas.drawRect(0, 0,frame.left, height,paint);
            canvas.drawRect(frame.left, 0, frame.right, frame.top, paint);
            canvas.drawRect(frame.right, 0, width, height, paint);
            canvas.drawRect(frame.left, frame.bottom, frame.right, height,
                    paint);

            // 画圆点标注
            canvas.drawCircle(frame.left, (frame.top + frame.bottom) / 2, 10,
                    tipPaint);
            canvas.drawCircle(frame.right, (frame.top + frame.bottom) / 2, 10,
                    tipPaint);
            canvas.drawCircle((frame.left + frame.right) / 2, frame.top, 10,
                    tipPaint);
            canvas.drawCircle((frame.left + frame.right) / 2, frame.bottom, 10,
                    tipPaint);


            // 画边框标注
//          canvas.drawCircle(frame.left, (frame.top + frame.bottom) / 2, 10,
//                  tipPaint);
//          
//          canvas.drawCircle(frame.right, (frame.top + frame.bottom) / 2, 10,
//                  tipPaint);
//          
//          canvas.drawCircle((frame.left + frame.right) / 2, frame.top, 10,
//                  tipPaint);
//          
//          canvas.drawCircle((frame.left + frame.right) / 2, frame.bottom, 10,
//                  tipPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {

        case MotionEvent.ACTION_DOWN:

            downX = (int) event.getX();
            downY = (int) event.getY();

            if (checkContainsPoint(downX, downY)) {

                touchInFrame = true;
                if ((downX > frame.left - 10 && downX < frame.left + 10)
                        && downY > frame.top && downY < frame.bottom) {
                    touchFrameLeft = true;
                }
                if ((downX > frame.right - 10 && downX < frame.right + 10)
                        && downY > frame.top && downY < frame.bottom) {
                    touchFrameRight = true;
                }
                if ((downX > frame.left && downX < frame.right)
                        && downY > frame.top - 10 && downY < frame.top + 10) {
                    touchFrameTop = true;
                }
                if ((downX > frame.left && downX < frame.right)
                        && downY > frame.bottom - 10
                        && downY < frame.bottom + 10) {
                    touchFrameBottom = true;
                }
            } else {
                touchInFrame = false;
            }

            break;
        case MotionEvent.ACTION_MOVE:
            if (!touchInFrame) {
                return true;
            }
            int currentX = (int) event.getX();
            int currentY = (int) event.getY();
            // 是否在边界上判断
            if (touchFrameLeft) {
                frame.left += currentX - downX;
                if (frame.left <= bitmapRect.left) {
                    frame.left = bitmapRect.left;
                }
                frameWidth = frame.right - frame.left;
                downX = currentX;
                invalidate();
                return true;
            }
            if (touchFrameRight) {
                frame.right += currentX - downX;
                if (frame.right >= bitmapRect.right) {
                    frame.right = bitmapRect.right;
                }
                frameWidth = frame.right - frame.left;
                downX = currentX;
                invalidate();
                return true;
            }
            if (touchFrameTop) {
                frame.top += currentY - downY;
                if (frame.top <= bitmapRect.top) {
                    frame.top = bitmapRect.top;
                }
                frameHeight = frame.bottom - frame.top;
                downY = currentY;
                invalidate();
                return true;
            }
            if (touchFrameBottom) {
                frame.bottom += currentY - downY;
                if (frame.bottom >= bitmapRect.bottom) {
                    frame.bottom = bitmapRect.bottom;
                }
                frameHeight = frame.bottom - frame.top;
                downY = currentY;

                invalidate();

                return true;
            }

            // 触摸发生不属于边界
            frame.left += currentX - downX;
            frame.right += currentX - downX;
            frame.top += currentY - downY;
            frame.bottom += currentY - downY;

            if (frame.left <= bitmapRect.left) {
                frame.left = bitmapRect.left;
                frame.right = bitmapRect.left + frameWidth;
            }
            if (frame.right >= bitmapRect.right) {
                frame.left = bitmapRect.right - frameWidth;
                frame.right = bitmapRect.right;
            }
            if (frame.top <= bitmapRect.top) {
                frame.top = bitmapRect.top;
                frame.bottom = bitmapRect.top + frameHeight;
            }
            if (frame.bottom >= bitmapRect.bottom) {
                frame.top = bitmapRect.bottom - frameHeight;
                frame.bottom = bitmapRect.bottom;
            }

            downX = currentX;
            downY = currentY;
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touchFrameLeft = false;
            touchFrameTop = false;
            touchFrameRight = false;
            touchFrameBottom = false;
            break;
        default:
            break;
        }
        return true;
    }

    public void setBitmap(Bitmap bitmap) {

        this.bitmap = bitmap;

        bitmapWidth = frameWidth = bitmap.getWidth();

        bitmapHeight = frameHeight = bitmap.getHeight();

        bitmapRect.left = (width - bitmapWidth) / 2;

        bitmapRect.right = width - (width - bitmapWidth) / 2;

        bitmapRect.top = (height - bitmapHeight) / 2;

        bitmapRect.bottom = height - (height - bitmapHeight) / 2;


        frame.left = bitmapRect.left;
        frame.right = bitmapRect.right;
        frame.top = bitmapRect.top;
        frame.bottom = bitmapRect.bottom;


        invalidate();
    }

    private boolean checkContainsPoint(int x, int y) {

        Rect boundsRect = new Rect();

        boundsRect.left = frame.left - 10;
        boundsRect.top = frame.top - 10;
        boundsRect.right = frame.right + 10;
        boundsRect.bottom = frame.bottom + 10;

        if (boundsRect.contains(x, y)) {

            return true;
        }

        return false;
    }

    /**
     * 获取需要裁剪的边界比例
     * 
     * @return
     */
    public List getClipScale() {

        List scales = new ArrayList();

        scales.add((frame.left - bitmapRect.left) * 1.0f / bitmapWidth);

        scales.add((bitmapRect.right - frame.right) * 1.0f / bitmapWidth);

        scales.add((frame.top - bitmapRect.top) * 1.0f / bitmapHeight);

        scales.add((bitmapRect.bottom - frame.bottom) * 1.0f / bitmapHeight);



        return scales;
    }
}

http://download.csdn.net/detail/luo446718254/9605345

你可能感兴趣的:(Android)