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 如何解决dialog弹出时无法捕捉Activity的back事件 在...
Android实现自定义带文字和图片的Button 在Android开发中经常...
Android 关于长按back键退出应用程序的实现最近在做一个Andr...
android自带的时间选择器只能精确到分,但是对于某些应用要求...