代码之家  ›  专栏  ›  技术社区  ›  Goku Farhana Naaz Ansari

如何在android中实现徒手图像裁剪?

  •  11
  • Goku Farhana Naaz Ansari  · 技术社区  · 7 年前

    Imageview .

    使用下面的代码,我可以画徒手画的路径,也可以裁剪图像,但我面临一些其他问题

    这是我的密码

    public class SomeView extends View implements View.OnTouchListener {
        private Paint paint;
    
        int DIST = 2;
        boolean flgPathDraw = true;
    
        Point mfirstpoint = null;
        boolean bfirstpoint = false;
    
        Point mlastpoint = null;
    
        Bitmap bitmap;
    
        Context mContext;
    
        public SomeView(Context c, Bitmap bitmap) {
            super(c);
    
            mContext = c;
            this.bitmap = bitmap;
    
            setFocusable(true);
            setFocusableInTouchMode(true);
    
            paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setStyle(Paint.Style.STROKE);
            paint.setPathEffect(new DashPathEffect(new float[]{10, 20}, 0));
            paint.setStrokeWidth(5);
            paint.setColor(Color.RED);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeCap(Paint.Cap.ROUND);
    
            this.setOnTouchListener(this);
            points = new ArrayList<Point>();
    
            bfirstpoint = false;
        }
    
        public SomeView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            mContext = context;
            setFocusable(true);
            setFocusableInTouchMode(true);
    
            paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(5);
            paint.setColor(Color.RED);
    
            points = new ArrayList<Point>();
            bfirstpoint = false;
    
            this.setOnTouchListener(this);
        }
    
        public void onDraw(Canvas canvas) {
    
            /*Rect dest = new Rect(0, 0, getWidth(), getHeight());
    
            paint.setFilterBitmap(true);
            canvas.drawBitmap(bitmap, null, dest, paint);*/
    
            canvas.drawBitmap(bitmap, 0, 0, null);
    
            Path path = new Path();
            boolean first = true;
    
            for (int i = 0; i < points.size(); i += 2) {
                Point point = points.get(i);
                if (first) {
                    first = false;
                    path.moveTo(point.x, point.y);
                } else if (i < points.size() - 1) {
                    Point next = points.get(i + 1);
                    path.quadTo(point.x, point.y, next.x, next.y);
                } else {
                    mlastpoint = points.get(i);
                    path.lineTo(point.x, point.y);
                }
            }
            canvas.drawPath(path, paint);
        }
    
        public boolean onTouch(View view, MotionEvent event) {
            // if(event.getAction() != MotionEvent.ACTION_DOWN)
            // return super.onTouchEvent(event);
    
            Point point = new Point();
            point.x = (int) event.getX();
            point.y = (int) event.getY();
    
            if (flgPathDraw) {
    
                if (bfirstpoint) {
    
                    if (comparepoint(mfirstpoint, point)) {
                        // points.add(point);
                        points.add(mfirstpoint);
                        flgPathDraw = false;
                        showcropdialog();
                    } else {
                        points.add(point);
                    }
                } else {
                    points.add(point);
                }
    
                if (!(bfirstpoint)) {
    
                    mfirstpoint = point;
                    bfirstpoint = true;
                }
            }
    
            invalidate();
            Log.e("Hi  ==>", "Size: " + point.x + " " + point.y);
    
            if (event.getAction() == MotionEvent.ACTION_UP) {
                Log.d("Action up*****~~>>>>", "called");
                mlastpoint = point;
                if (flgPathDraw) {
                    if (points.size() > 12) {
                        if (!comparepoint(mfirstpoint, mlastpoint)) {
                            flgPathDraw = false;
                            points.add(mfirstpoint);
                            showcropdialog();
                        }
                    }
                }
            }
    
            return true;
        }
    
        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 (points.size() < 10) {
                    return false;
                } else {
                    return true;
                }
            } else {
                return false;
            }
    
        }
    
        public void fillinPartofPath() {
            Point point = new Point();
            point.x = points.get(0).x;
            point.y = points.get(0).y;
    
            points.add(point);
            invalidate();
        }
    
        public void resetView() {
            points.clear();
            paint.setColor(Color.WHITE);
            paint.setStyle(Paint.Style.STROKE);
    
            paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(5);
            paint.setColor(Color.RED);
    
            points = new ArrayList<Point>();
            bfirstpoint = false;
    
            flgPathDraw = true;
            invalidate();
        }
    
        private void showcropdialog() {
            DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent;
                    switch (which) {
                        case DialogInterface.BUTTON_POSITIVE:
                            cropImage();
                            break;
    
                        case DialogInterface.BUTTON_NEGATIVE:
                            /*// No button clicked
    
                            intent = new Intent(mContext, DisplayCropActivity.class);
                            intent.putExtra("crop", false);
                            mContext.startActivity(intent);
    
                            bfirstpoint = false;*/
                            resetView();
    
                            break;
                    }
                }
            };
    
            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
            builder.setMessage("Do you Want to save Crop or Non-crop image?")
                    .setPositiveButton("Crop", dialogClickListener)
                    .setNegativeButton("Non-crop", dialogClickListener).show()
                    .setCancelable(false);
        }
    }
    

    裁剪位图的代码

    public void cropImage() {
    
        setContentView(R.layout.activity_picture_preview);
    
        imageView = findViewById(R.id.image);
    
        int widthOfscreen = 0;
        int heightOfScreen = 0;
    
        DisplayMetrics dm = new DisplayMetrics();
        try {
            getWindowManager().getDefaultDisplay().getMetrics(dm);
        } catch (Exception ex) {
        }
        widthOfscreen = dm.widthPixels;
        heightOfScreen = dm.heightPixels;
    
        Bitmap bitmap2 = mBitmap;
    
        Bitmap resultingImage = Bitmap.createBitmap(widthOfscreen,
                heightOfScreen, bitmap2.getConfig());
    
        Canvas canvas = new Canvas(resultingImage);
    
        Paint paint = new Paint();
    
        Path path = new Path();
    
        for (int i = 0; i < points.size(); i++) {
    
            path.lineTo(points.get(i).x, points.get(i).y);
    
        }
    
        canvas.drawPath(path, paint);
    
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    
        canvas.drawBitmap(bitmap2, 0, 0, paint);
    
        imageView.setImageBitmap(resultingImage);
    
    }
    

    Cropping image using Finger touch

    This image showing result after cropping image

    这是我的预期输出

    请检查下面的屏幕截图以了解相同的信息

    This Image showing cropping image using Finger touch

    This image showing result after cropping image

    下面是我在上面代码中面临的问题

    • 若我在画布上全屏设置位图,那个么图像将被拉伸
    • 如何将透明背景设置为裁剪的位图
    • 图像裁剪的结果与预期不符

    这里有一些其他的帖子,我到目前为止已经试过了

    3 回复  |  直到 7 年前
        1
  •  13
  •   Cheticamp    7 年前

    一般来说,您的代码看起来不错,但我有几点意见:

    • 无法使用画布全屏设置位图

    • 您选择的图像部分需要放置在较小的位图中,以便布局XML可以根据您的喜好对其进行定位。您正在创建一个全屏位图。有关详细信息,请参见下面的演示。

    • 如何将透明背景设置为裁剪的位图

    • 图像裁剪的结果与预期不符
      见下文。

    MCVE ,因此我将以下内容放在一起进行演示。除了让应用程序正常运行之外,我认为唯一的改变是在应用程序中绘制边界 MainActivity.java . 边框宽度从用户绘制的切口路径开始,并向内延伸到切口。如果您想在不丢失任何像素的情况下实际设置剪切帧,则需要扩展路径以适应我任意设置为20像素的帧。

    enter image description here

    public class MainActivity extends AppCompatActivity {
        private Bitmap mBitmap;
        private SomeView mSomeView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dog);
            mSomeView = new SomeView(this, mBitmap);
            LinearLayout layout = findViewById(R.id.layout);
            LinearLayout.LayoutParams lp =
                new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                                              LinearLayout.LayoutParams.WRAP_CONTENT);
            layout.addView(mSomeView, lp);
        }
    
        public void cropImage() {
            setContentView(R.layout.activity_picture_preview);
            ImageView imageView = findViewById(R.id.image);
    
            Bitmap fullScreenBitmap =
                Bitmap.createBitmap(mSomeView.getWidth(), mSomeView.getHeight(), mBitmap.getConfig());
    
            Canvas canvas = new Canvas(fullScreenBitmap);
    
            Path path = new Path();
            List<Point> points = mSomeView.getPoints();
            for (int i = 0; i < points.size(); i++) {
                path.lineTo(points.get(i).x, points.get(i).y);
            }
    
            // Cut out the selected portion of the image...
            Paint paint = new Paint();
            canvas.drawPath(path, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(mBitmap, 0, 0, paint);
    
            // Frame the cut out portion...
            paint.setColor(Color.WHITE);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(10f);
            canvas.drawPath(path, paint);
    
            // Create a bitmap with just the cropped area.
            Region region = new Region();
            Region clip = new Region(0, 0, fullScreenBitmap.getWidth(), fullScreenBitmap.getHeight());
            region.setPath(path, clip);
            Rect bounds = region.getBounds();
            Bitmap croppedBitmap =
                Bitmap.createBitmap(fullScreenBitmap, bounds.left, bounds.top,
                                    bounds.width(), bounds.height());
    
            imageView.setImageBitmap(croppedBitmap);
        }
    }
    

    SomeView.java
    我认为这门课没有任何实质性的变化。

    public class SomeView extends View implements View.OnTouchListener {  
        private Paint paint;  
        private List<Point> points;  
    
        int DIST = 2;  
        boolean flgPathDraw = true;  
    
        Point mfirstpoint = null;  
        boolean bfirstpoint = false;  
    
        Point mlastpoint = null;  
    
        Bitmap bitmap;  
    
        Context mContext;  
    
    
            public SomeView(Context c, Bitmap bitmap) {  
                super(c);  
    
                mContext = c;  
                this.bitmap = bitmap;  
    
                setFocusable(true);  
                setFocusableInTouchMode(true);  
    
                paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
                paint.setStyle(Paint.Style.STROKE);  
                paint.setPathEffect(new DashPathEffect(new float[]{10, 20}, 0));  
                paint.setStrokeWidth(5);  
                paint.setColor(Color.RED);  
                paint.setStrokeJoin(Paint.Join.ROUND);  
                paint.setStrokeCap(Paint.Cap.ROUND);  
    
                this.setOnTouchListener(this);  
                points = new ArrayList<Point>();  
    
                bfirstpoint = false;  
            }  
    
            public SomeView(Context context, AttributeSet attrs) {  
                super(context, attrs);  
    
                mContext = context;  
                setFocusable(true);  
                setFocusableInTouchMode(true);  
    
                paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
                paint.setStyle(Paint.Style.STROKE);  
                paint.setStrokeWidth(5);  
                paint.setColor(Color.RED);  
    
                points = new ArrayList<Point>();  
                bfirstpoint = false;  
    
                this.setOnTouchListener(this);  
            }  
    
            public void onDraw(Canvas canvas) {  
    
                /*Rect dest = new Rect(0, 0, getWidth(), getHeight());  
    
         paint.setFilterBitmap(true); canvas.drawBitmap(bitmap, null, dest, paint);*/  
          canvas.drawBitmap(bitmap, 0, 0, null);  
    
                Path path = new Path();  
                boolean first = true;  
    
                for (int i = 0; i < points.size(); i += 2) {  
                    Point point = points.get(i);  
                    if (first) {  
                        first = false;  
                        path.moveTo(point.x, point.y);  
                    } else if (i < points.size() - 1) {  
                        Point next = points.get(i + 1);  
                        path.quadTo(point.x, point.y, next.x, next.y);  
                    } else {  
                        mlastpoint = points.get(i);  
                        path.lineTo(point.x, point.y);  
                    }  
                }  
                canvas.drawPath(path, paint);  
            }  
    
            public boolean onTouch(View view, MotionEvent event) {  
                // if(event.getAction() != MotionEvent.ACTION_DOWN)  
         // return super.onTouchEvent(event);  
          Point point = new Point();  
                point.x = (int) event.getX();  
                point.y = (int) event.getY();  
    
                if (flgPathDraw) {  
    
                    if (bfirstpoint) {  
    
                        if (comparepoint(mfirstpoint, point)) {  
                            // points.add(point);  
          points.add(mfirstpoint);  
                            flgPathDraw = false;  
                            showcropdialog();  
                        } else {  
                            points.add(point);  
                        }  
                    } else {  
                        points.add(point);  
                    }  
    
                    if (!(bfirstpoint)) {  
    
                        mfirstpoint = point;  
                        bfirstpoint = true;  
                    }  
                }  
    
                invalidate();  
                Log.e("Hi  ==>", "Size: " + point.x + " " + point.y);  
    
                if (event.getAction() == MotionEvent.ACTION_UP) {  
                    Log.d("Action up*****~~>>>>", "called");  
                    mlastpoint = point;  
                    if (flgPathDraw) {  
                        if (points.size() > 12) {  
                            if (!comparepoint(mfirstpoint, mlastpoint)) {  
                                flgPathDraw = false;  
                                points.add(mfirstpoint);  
                                showcropdialog();  
                            }  
                        }  
                    }  
                }  
    
                return true;  
            }  
    
            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 (points.size() < 10) {  
                        return false;  
                    } else {  
                        return true;  
                    }  
                } else {  
                    return false;  
                }  
    
            }  
    
            public void fillinPartofPath() {  
                Point point = new Point();  
                point.x = points.get(0).x;  
                point.y = points.get(0).y;  
    
                points.add(point);  
                invalidate();  
            }  
    
            public void resetView() {  
                points.clear();  
                paint.setColor(Color.WHITE);  
                paint.setStyle(Paint.Style.STROKE);  
    
                paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
                paint.setStyle(Paint.Style.STROKE);  
                paint.setStrokeWidth(5);  
                paint.setColor(Color.RED);  
    
                points = new ArrayList<Point>();  
                bfirstpoint = false;  
    
                flgPathDraw = true;  
                invalidate();  
            }  
    
            private void showcropdialog() {  
                DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {  
                    @Override  
          public void onClick(DialogInterface dialog, int which) {  
                        Intent intent;  
                        switch (which) {  
                            case DialogInterface.BUTTON_POSITIVE:  
                                ((MainActivity) mContext).cropImage();  
                                break;  
    
                            case DialogInterface.BUTTON_NEGATIVE:  
                                /*// No button clicked  
    
         intent = new Intent(mContext, DisplayCropActivity.class); intent.putExtra("crop", false); mContext.startActivity(intent);  
         bfirstpoint = false;*/  resetView();  
    
                                break;  
                        }  
                    }  
                };  
    
                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);  
                builder.setMessage("Do you Want to save Crop or Non-crop image?")  
                    .setPositiveButton("Crop", dialogClickListener)  
                    .setNegativeButton("Non-crop", dialogClickListener).show()  
                    .setCancelable(false);  
            }  
    
            public List<Point> getPoints() {  
                return points;  
            }  
        }
    

    <LinearLayout 
      android:id="@+id/layout"  
      xmlns:tools="http://schemas.android.com/tools"  
      android:layout_width="match_parent"  
      android:layout_height="match_parent"  
      android:orientation="vertical"  
      tools:context=".MainActivity"/>
    

    <android.support.constraint.ConstraintLayout x
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary">
    
        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:srcCompat="@drawable/dog" />
    </android.support.constraint.ConstraintLayout> 
    

    cropImage() :

        // Create a bitmap with just the cropped area.
        Region region = new Region();
        Region clip = new Region(0, 0, fullScreenBitmap.getWidth(), fullScreenBitmap.getHeight());
        region.setPath(path, clip);
        Rect sourceBounds = region.getBounds();
        Rect destBounds =
            new Rect(CROPPED_MARGIN, CROPPED_MARGIN, sourceBounds.width() + CROPPED_MARGIN,
                     sourceBounds.height() + CROPPED_MARGIN);
        Bitmap croppedBitmap =
            Bitmap.createBitmap(sourceBounds.width() + CROPPED_MARGIN * 2,
                                sourceBounds.height() + CROPPED_MARGIN * 2, mBitmap.getConfig());
        canvas.setBitmap(croppedBitmap);
        canvas.drawBitmap(fullScreenBitmap, sourceBounds, destBounds, null);
    
        imageView.setImageBitmap(croppedBitmap);
    
        // Add as member variable.
        private static final int CROPPED_MARGIN = 100;
    
        2
  •  1
  •   Krishna Vyas nickson makama    7 年前

    在我的项目中,我已经尝试了很多解决这个问题的方法,但是这段代码仍然有效。 在这里,我把我自己的项目代码放在这里。如果您在其中找到了解决方案,您可以使用它。

    public class CropView extends View implements View.OnTouchListener {
    public static final String INTENT_KEY_CROP = "crop";
    public static final String CACHE_KEY = "bitmap";
    
    public static List<Point> points;
    boolean flgPathDraw = true;
    boolean bFirstPoint = false;
    private Point firstPoint = null;
    private Point lastPoint = null;
    
    private final Bitmap originalImageBitmap;
    private int canvasWidth;
    private int canvasHeight;
    private Paint paint;
    private Context context;
    private static LruCache<String, Bitmap> mMemoryCache;
    private final ImageCropListener imageCropListener;
    
    public interface ImageCropListener {
        void onClickDialogPositiveButton();
        void onClickDialogNegativeButton();
    }
    
    public static Bitmap getBitmapFromMemCache() {
        return mMemoryCache.get(CACHE_KEY);
    }
    
    
    public CropView(Context c, Bitmap bm, ImageCropListener listener) {
        super(c);
    
        context = c;
        setFocusable(true);
        setFocusableInTouchMode(true);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setPathEffect(new DashPathEffect(new float[] { 10, 20 }, 0));
        paint.setStrokeWidth(5);
        paint.setColor(Color.WHITE);
    
        this.setOnTouchListener(this);
        points = new ArrayList<>();
    
        bFirstPoint = false;
        this.originalImageBitmap = bm;
        this.imageCropListener = listener;
    
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                return bitmap.getByteCount() / 1024;
            }
        };
    
     }
    
     public CropView(Context context, AttributeSet attrs, Bitmap bm, 
     ImageCropListener listener) {
        super(context, attrs);
        this.context = context;
        setFocusable(true);
        setFocusableInTouchMode(true);
    
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        paint.setColor(Color.WHITE);
    
        this.setOnTouchListener(this);
        points = new ArrayList<>();
        bFirstPoint = false;
        this.originalImageBitmap = bm;
        this.imageCropListener = listener;
    }
    
    public void addBitmapToMemoryCache(Bitmap bitmap) {
        if (getBitmapFromMemCache() == null) {
            mMemoryCache.put(CACHE_KEY, bitmap);
        }
    }
    
    private float calcBitmapScale(int canvasWidth, int canvasHeight, int bmpWidth, int bmpHeight) {
    
        float scale = (float)canvasWidth / (float)bmpWidth;
        float tmp = bmpHeight * scale;
    
        if (tmp < canvasHeight) {
            scale = (float)canvasHeight / (float)bmpHeight;
            return scale;
        }
    
        return scale;
    }
    
    public void onDraw(Canvas canvas) {
        canvasWidth = canvas.getWidth();
        canvasHeight = canvas.getHeight();
    
       /* int bmpWidth = this.originalImageBitmap.getWidth();
        int bmpHeight = this.originalImageBitmap.getHeight();
    
    
        float toCanvasScale = this.calcBitmapScale(canvasWidth, canvasHeight, bmpWidth, bmpHeight);
    
    
        float diffX = (bmpWidth * toCanvasScale - canvasWidth);
        float diffY = (bmpHeight * toCanvasScale - canvasHeight);
    
    
        float addX = (diffX / toCanvasScale) / 2;
        float addY = (diffY / toCanvasScale) / 2;
    
    
        Rect rSrc = new Rect((int)addX, (int)addY,
                (int)((canvasWidth / toCanvasScale) + addX), (int)((canvasHeight / 
        toCanvasScale) + addY));
        RectF rDest = new RectF(0, 0, canvasWidth, canvasHeight);
        */
        canvas.drawBitmap(originalImageBitmap, 0, 0, null);
    
        Path cropAreaPath = new Path();
        boolean isFirstPoint = true;
    
        for (int i = 0; i < points.size(); i += 2) {
            Point point = points.get(i);
            if (isFirstPoint) {
                isFirstPoint = false;
                // 最初の処理でPathのx,y座標をpointの座標に移動する
                cropAreaPath.moveTo(point.x, point.y);
            } else if (i < points.size() - 1) {
                Point next = points.get(i + 1);
                cropAreaPath.quadTo(point.x, point.y, next.x, next.y);
            } else {
                lastPoint = points.get(i);
                cropAreaPath.lineTo(point.x, point.y);
            }
        }
        canvas.drawPath(cropAreaPath, paint);
    }
    
    public boolean onTouch(View view, MotionEvent event) {
        Point point = new Point();
        point.x = (int) event.getX();
        point.y = (int) event.getY();
    
        if (flgPathDraw) {
            if (bFirstPoint) {
                if (comparePoint(firstPoint, point)) {
                    // points.add(point);
                    points.add(firstPoint);
                    flgPathDraw = false;
                    showCropDialog();
                } else {
                    points.add(point);
                }
            } else {
                points.add(point);
            }
    
            if (!(bFirstPoint)) {
    
                firstPoint = point;
                bFirstPoint = true;
            }
        }
    
        invalidate();
        //Log.e("Hi  ==>", "Size: " + point.x + " " + point.y);
    
        if (event.getAction() == MotionEvent.ACTION_UP) {
            Log.d("Action up***>", "called");
            lastPoint = point;
            if (flgPathDraw) {
                if (points.size() > 12) {
                    if (!comparePoint(firstPoint, lastPoint)) {
                        flgPathDraw = false;
                        points.add(firstPoint);
                        showCropDialog();
                    }
                }
            }
        }
    
        return true;
    }
    
    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 (points.size() < 10) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    
    }
    
    public void fillinPartofPath() {
        Point point = new Point();
        point.x = points.get(0).x;
        point.y = points.get(0).y;
    
        points.add(point);
        invalidate();
    }
    
    public void resetView() {
        points.clear();
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        flgPathDraw = true;
        invalidate();
    }
    
    private void showCropDialog() {
        final Bitmap croppedImage = cropImage(this.originalImageBitmap);
        DialogInterface.OnClickListener dialogClickListener = new 
        DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case DialogInterface.BUTTON_POSITIVE:
                        addBitmapToMemoryCache(croppedImage);
                        imageCropListener.onClickDialogPositiveButton();
                        break;
    
                    case DialogInterface.BUTTON_NEGATIVE:
                        bFirstPoint = false;
                        resetView();
                        imageCropListener.onClickDialogNegativeButton();
                        break;
                }
            }
        };
    
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage("Do you Want to save Crop or Non-crop image?")
                .setPositiveButton("Crop", dialogClickListener)
                .setNegativeButton("Cancel", dialogClickListener).show()
                .setCancelable(false);
    }
    
    private Bitmap cropImage(Bitmap image) {
        Bitmap cropImage = Bitmap.createBitmap(canvasWidth, canvasHeight, 
        image.getConfig());
        Canvas canvas = new Canvas(cropImage);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
    
        Path path = new Path();
        for (int i = 0; i < CropView.points.size(); i++) {
            path.lineTo(CropView.points.get(i).x, CropView.points.get(i).y);
        }
        canvas.drawPath(path, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(originalImageBitmap, 0, 0, paint);
    
        return cropImage;
    }
    
    class Point {
        public float dy;
        public float dx;
        float x, y;
    
        @Override
        public String toString(){
            return x + ", " + y;
        }
    }
    }
    

    然后你可以得到裁剪结果,就像,

    Bitmap cropBitmap = CropView.getBitmapFromMemCache();
                    cropBitmap = getBitmapWithTransparentBG(cropBitmap,Color.WHITE);
                    Drawable d = new BitmapDrawable(getResources(),cropBitmap);
    
    public Bitmap getBitmapWithTransparentBG(Bitmap srcBitmap, int bgColor) {
        Bitmap result = srcBitmap.copy(Bitmap.Config.ARGB_8888, true);
        int nWidth = result.getWidth();
        int nHeight = result.getHeight();
        for (int y = 0; y < nHeight; ++y)
            for (int x = 0; x < nWidth; ++x) {
                int nPixelColor = result.getPixel(x, y);
                if (nPixelColor == bgColor)
                    result.setPixel(x, y, Color.TRANSPARENT);
            }
        return result;
    }
    

    我认为,这段代码将非常适合您的问题解决方案。。谢谢