Android在缩放图像上绘制

时间:2016-06-07 21:53:41

标签: android canvas zoom paint drag

我试图在ImageView上绘制一些点,这些点还具有DRAG和ZOOM功能。

如果图像未被修改(缩放或拖动),我的实现工作正常,但如果我应用这些类型的转换,它将不再正确绘制。 相反,它会将初始框架作为参考,并将绘制点,就好像它没有被修改。

这是从图库中选择图像并通过点击它绘制绿点后的图像。

unaltered image

这是放大图像并将其拖到侧面后图像的样子。正如您所看到的,如果我在初始帧内点击,它会在图像内部绘制一个点,就好像它是未缩放的一样。

altered image

Bellow是代码(从图库中选择图片,onTouch方法和实际图纸)。

public void onClick(View v) {

    if (v.getId()==R.id.putPoint){
        drawPath=true;
    }
    else
    if (v == choosePicture) {
        Intent choosePictureIntent = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(choosePictureIntent, 0);
    }
}

protected void onActivityResult(int requestCode, int resultCode,
                                Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (resultCode == RESULT_OK) {
        Uri imageFileUri = intent.getData();
        try {
            BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
            bmpFactoryOptions.inJustDecodeBounds = true;
            bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                    imageFileUri), null, bmpFactoryOptions);

            bmpFactoryOptions.inJustDecodeBounds = false;
            bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                    imageFileUri), null, bmpFactoryOptions);


            alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp
                    .getHeight(), bmp.getConfig());

            canvas = new Canvas(alteredBitmap);
            paint = new Paint();
            paint.setColor(Color.GREEN);
            paint.setStrokeWidth(5);
            matrix = new Matrix();
            canvas.drawBitmap(bmp, matrix, paint);

            choosenImageView.setImageBitmap(alteredBitmap);
            choosenImageView.setOnTouchListener(this);
        } catch (Exception e) {
            Log.v("ERROR", e.toString());
        }
    }
}
public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();
    ImageView view = (ImageView) v;
    if(drawPath) {
    //I use this flag to enable drawing mode

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                downx = event.getX();
                downy = event.getY();
                canvas.drawCircle(downx, downy, radius,paint);
                choosenImageView.invalidate();
                drawPath=false;
                break;

        }
        return true;
    }
    else{
        //if the drawing mode is not enable I can zoom and drag the image
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix);
                start.set(event.getX(), event.getY());
                mode = DRAG;
                lastEvent = null;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    mode = ZOOM;
                }
                lastEvent = new float[4];
                lastEvent[0] = event.getX(0);
                lastEvent[1] = event.getX(1);
                lastEvent[2] = event.getY(0);
                lastEvent[3] = event.getY(1);
                d = rotation(event);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                lastEvent = null;

                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {
                    matrix.set(savedMatrix);
                    float dx = event.getX() - start.x;
                    float dy = event.getY() - start.y;
                    matrix.postTranslate(dx, dy);

                } else if (mode == ZOOM) {
                    float newDist = spacing(event);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = (newDist / oldDist);
                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
                }
                break;
        }

        view.setImageMatrix(matrix);
        return true;

    }
}

}

我的目标是能够点按图像(zommed或拖动)并看到正确绘制的点。

1 个答案:

答案 0 :(得分:0)

请参阅:How do I get touch coordinates with respect to canvas after scaling and translating?

最简单,最一致的方法是应用用于修改视图的逆矩阵来修改MotionEvent。您需要了解两个命令:

event.transform(invertMatrix);

和:

invertMatrix = new Matrix(viewMatrix);
invertMatrix.invert(invertMatrix);

基本上,您所做的与触摸视图相反。因此,触摸就进入了场景空间。