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

时间:2013-07-12 05:32:31

标签: android bitmap

我正在制作一个应用程序我最近3天无法解决一个问题谷歌尽可能多。我在画布上制作一个圆圈并想要裁剪图像那部分并在缩放模式下显示该图像。我的第一步就像在屏幕在这里: - enter image description 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();
}

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

但添加所选区域的精确坐标时如: -

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)

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

1 个答案:

答案 0 :(得分:6)

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