android – 如何在画布上选择区域的裁剪位图?

我正在制作一个应用程序我最近3天无法解决一个问题google尽可能多.我在画布上制作一个圆圈并想要裁剪图像那部分并在缩放模式下显示该图像.我的第一步就像在屏幕上这样: –

在这个我选择区域.我使用的代码就是这个.

private float x,y;
private boolean zooming = false;
private Paint mPaint;
private Matrix mmatrix;
private Shader mShader;
private Bitmap mBitmap;
private  List<Point> mpoints;
private List<MyPoints> mpointlist;
private Path mpath;
private Canvas mcanvas;
private Bitmap mresult_bitmap,resultingImage,finalbitmap;
private Context mcontext;
private boolean bfirstpoint = false;
private Point mfirstpoint = null;
private Point mlastpoint = null;

public CircularZoomView(Context context) {
    super(context);
    mcontext = context;
    mpath = new Path();
    mpoints = new ArrayList<Point>();
    setBackgroundResource(R.drawable.testing);
    mPaint = new Paint();

    mresult_bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.testing);

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setStyle(Paint.Style.stroke);
    mPaint.setPathEffect(new DashPathEffect(new float[] { 10,20 },0));
    mPaint.setstrokeWidth(5);
    mPaint.setColor(Color.RED);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (zooming && resultingImage!=null) {
        zooming = false;
        ShowImage(resultingImage);
        canvas.drawBitmap(resultingImage,mmatrix,null);
    }
    boolean first = true;

    for (int i = 0; i < mpoints.size(); i += 2) {
        Point point = mpoints.get(i);
        if (first) {
            first = false;
            mpath.moveto(point.x,point.y);
        } else if (i < mpoints.size() - 1) {
            Point next = mpoints.get(i + 1);
            mpath.quadTo(point.x,point.y,next.x,next.y);
        } else {
            mlastpoint = mpoints.get(i);
            mpath.lineto(point.x,point.y);
        }
    }

    canvas.drawPath(mpath,mPaint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    int action = event.getAction();

    x = event.getX();
    y = event.getY();

    Point point = new Point();
    point.x = (int) event.getX();
    point.y = (int) event.getY();

    if (bfirstpoint) {
        if (comparepoint(mfirstpoint,point)) {
            mpoints.add(mfirstpoint);
            addCircleFromPath(mpath);
        } else {
            mpoints.add(point);
        }
    } else {
        mpoints.add(point);
    }

    if (!(bfirstpoint)) {
        mfirstpoint = point;
        bfirstpoint = true;
    }

    invalidate();

    switch (action) {
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_MOVE:

        zooming = false;
        this.invalidate();
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        zooming = true;
        mlastpoint = point;
            if (mpoints.size() > 12) {
                if (!comparepoint(mfirstpoint,mlastpoint)) {
                    mpoints.add(mfirstpoint);
                    addCircleFromPath(mpath);
                }
            }
        this.invalidate();
        break;

    default:
        break;
    }

    return true;
}


public Bitmap getCroppedBitmap(Bitmap bitmap) {

    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0,bitmap.getWidth(),bitmap.getHeight());

    paint.setAntiAlias(true);
    canvas.drawARGB(0,0);
    paint.setColor(color);
    canvas.drawCircle(bitmap.getWidth() / 2,bitmap.getHeight() / 2,bitmap.getWidth() / 2,paint);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap,rect,paint);
    return output;
}



void ShowImage(Bitmap mbitmap) {
    display display = ((MainActivity) mcontext).getwindowManager().getDefaultdisplay(); 
    int screenWidth = display.getWidth();
    float imageWidth = (float)mbitmap.getWidth();
    float imageHeight = (float)mbitmap.getHeight();
    float newHeight = imageHeight / (imageWidth / screenWidth);
    float newWidth = screenWidth;
    float scaleWidth = screenWidth / imageWidth;
    float scaleHeight = newHeight / imageHeight;
    SetimageMatrix(mbitmap,scaleWidth,scaleHeight);

    }

void SetimageMatrix(Bitmap image,float scaleWidth,float scaleHeight) {
    mmatrix = new Matrix();
    mmatrix.setTranslate(40,40);
    mmatrix.postScale(scaleWidth/2,scaleHeight/2);
    /*image.setimageMatrix(mmatrix);
    image.setScaleType(ScaleType.MATRIX);
    image.invalidate();*/

    }

private boolean comparepoint(Point first,Point current) {
    int left_range_x = (int) (current.x - 3);
    int left_range_y = (int) (current.y - 3);

    int right_range_x = (int) (current.x + 3);
    int right_range_y = (int) (current.y + 3);


    if ((left_range_x < first.x && first.x < right_range_x)
            && (left_range_y < first.y && first.y < right_range_y)) {
        if (mpoints.size() < 10) {
            return false;
        } else {
            return true;
        }
    } else {
        return false;
    }

}

private void addCircleFromPath(Path path){
    RectF bounds = new RectF();
    path.computeBounds(bounds,true);
    int width = (int) (bounds.right-bounds.left);
    int height = (int) (bounds.bottom-bounds.top);
    if(width<20 && height<20){
        path.reset();
        return;
    }
    int radius  ; 
    if(width>=height)
        radius = Math.round(((width/2))); 
    else radius = Math.round((int) ((height/2)));
    /*CircleTagObject circle = new CircleTagObject((int)bounds.left+width/2,(int)bounds.top+height/2,radius,crossBitmap,tagBitmap,circleArray.size(),ImageEditorView.this);
    circleArray.add(circle);
    tagBallID = circleArray.size() - 1;
    dragEnable = true;*/

    resultingImage = getCroppedBitmap(Bitmap.createBitmap(mresult_bitmap,200,200));
    mcanvas = new Canvas(resultingImage);
    path.reset();
    resetView();
    invalidate();
}

public void resetView() {
    mpoints.clear();
    mPaint.setStyle(Paint.Style.stroke);
    mPaint.setPathEffect(new DashPathEffect(new float[] { 10,0));
    mPaint.setstrokeWidth(5);
    mPaint.setColor(Color.RED);
    invalidate();
}

如果我像上面那样创建硬编码位图,它显示的是好的但不是所选部分的裁剪位图.就像这个图像一样.

但是当添加所选区域的精确坐标时如: –

resultingImage = getCroppedBitmap(Bitmap.createBitmap(mresult_bitmap,(int)bounds.left,(int)bounds.top,width,height));

然后发生异常: –

07-12 10:58:56.700: E/MessageQueue-JNI(12310): java.lang.IllegalArgumentException: y + height must be <= bitmap.height()
07-12 10:58:56.700: E/MessageQueue-JNI(12310):  at android.graphics.Bitmap.createBitmap(Bitmap.java:565)
07-12 10:58:56.700: E/MessageQueue-JNI(12310):  at android.graphics.Bitmap.createBitmap(Bitmap.java:530)
07-12 10:58:56.700: E/MessageQueue-JNI(12310):  at com.intel.view.CircularZoomView.addCircleFromPath(CircularZoomView.java:237)

我知道为什么会发生此异常,但无法找到解决方案如何裁剪所选部分的裁剪图像.提前谢谢.

解决方法

我知道你的解决方案为时已晚,但这可能对其他人有帮助 Use of this code 帮助你摆脱这个问题.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...