如何在canvas上裁剪选定区域的位图?

我正在做一个应用程序,我不能一个问题最后三天做谷歌尽可能多。我在canvas上做一个圆圈,并要裁剪图像的那部分,并显示在缩放模式的图像。我的第一步就像在屏幕这里: – 在这里输入图像说明

在这里,我selectarea.here是我的代码使用这个。

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, 0, bitmap.getWidth(), bitmap.getHeight()); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 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, 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,0,0,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, 20 }, 0)); mPaint.setStrokeWidth(5); mPaint.setColor(Color.RED); invalidate(); } 

如果我创build硬编码位图像上面显示好,但不裁剪位图的选定part.Like此图像。 在这里输入图像说明

但是当添加选定区域的精确坐标像: –

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

然后发生exception: –

  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) 

我知道为什么会发生这种exception,但无法find解决scheme如何裁剪选定部分的图像。提前感谢。

Solutions Collecting From Web of "如何在canvas上裁剪选定区域的位图?"