Android的 - 如何圆形变焦/放大图像的一部分吗?(Android - How to circ

2019-07-05 05:14发布

我试图让用户触摸图像,然后基本上是一个圆环形放大镜将显示,让用户更好地选择在图像上的某个区域。 当用户释放触摸放大部分将dissapear。 这是用来在几个照片编辑应用程序,我想实现我自己的版本。 我有下面的代码做放大的ImageView的圆形部分,但不会删除或清除缩放一次我释放我的手指。 我目前使用设置位图以一个帆布canvas = new Canvas(bitMap); 然后设置使用的ImageView takenPhoto.setImageBitmap(bitMap); 我不知道如果我要它的正确途径。 该onTouch代码如下:

zoomPos = new PointF(0,0);
        takenPhoto.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                 int action = event.getAction(); 
                    switch (action) { 
                        case MotionEvent.ACTION_DOWN: 
                            zoomPos.x = event.getX();
                            zoomPos.y = event.getY();
                            matrix.reset();
                            matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
                            shader.setLocalMatrix(matrix);
                            canvas.drawCircle(zoomPos.x, zoomPos.y, 20, shaderPaint);
                            takenPhoto.invalidate();
                            break; 
                        case MotionEvent.ACTION_MOVE: 
                            zoomPos.x = event.getX();
                            zoomPos.y = event.getY();
                            matrix.reset();
                            matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
                            canvas.drawCircle(zoomPos.x, zoomPos.y, 20, shaderPaint);
                            takenPhoto.invalidate();
                            break; 
                        case MotionEvent.ACTION_UP:   
                            //clear zoom here?

                            break; 
                        case MotionEvent.ACTION_CANCEL: 
                            break; 
                        default: 
                            break; 
            }
                    return true; 
            } 
            });

Answer 1:

适应你的代码,我能得到以下办法工作。

在onTouch功能,设置一个全球性的点确定在用户触摸,并设置一个布尔值,表明变焦当前是否激活与否:

@Override
public boolean onTouch(View view, MotionEvent event) {

    int action = event.getAction(); 

    zoomPos.x = event.getX();
    zoomPos.y = event.getY();

    switch (action) { 
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_MOVE:
        zooming = true;
        this.invalidate();
        break; 
    case MotionEvent.ACTION_UP:   
    case MotionEvent.ACTION_CANCEL:
        zooming = false;
        this.invalidate();
        break; 

    default: 
        break; 
    }

    return true; 
}

然后,在的onDraw方法,你用你的代码,用于绘制部分的放大:

@Override
protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);

    if (zooming) {
        matrix.reset();
        matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
        mPaint.getShader().setLocalMatrix(matrix);

        canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint);
    }
}

请注意,着色器,我作为描述的位图着色器在这里 ,这是与创建:

mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
mShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);

mPaint = new Paint();
mPaint.setShader(mShader);


Answer 2:

恢复到图像所做的任何更改的最佳方式将是从源文件重新加载图像。 或可替换地,保持一份原始矩阵变量转换开始之前,期间MotionEvent.ACTION_UP加载原始矩阵。



Answer 3:

有人问了一个固定的地方放大镜位置,我尝试它,并用该溶液想出了:

// bitmapWidth is the width of bitmap used for BitmapShader
// bitmapHeight is the height of bitmap used for BitmapShader
// canvasWidth is the width of canvas where the zoom touch events are tracked (usually has the same image as shader but can be different size)
// canvasHeight is the height of canvas where the zoom touch events are tracked
// touchPoint is the point on the canvas which area should be shown in zoom circle
// fixedZoomPoint is the center of the zoom circle (different from touch point)
// ZOOM_SCALE is the zooming ratio (e.g.: 2f)
// ZOOM_RADIUS is the radius of the zoom circle

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    if (zooming) {
        val widthRatio = bitmapWidth / canvasWidth // This can be omitted if 1.0
        val heightRatio = bitmapHeight / canvasHeight // This can be omitted if 1.0
        matrix.reset()
        matrix.postScale(ZOOM_SCALE, ZOOM_SCALE, touchPoint.x * widthRatio, touchPoint.y * heightRatio)
        matrix.postTranslate(fixedZoomPoint.x - touchPoint.x * widthRatio, fixedZoomPoint.y - touchPoint.y * heightRatio)
        paint.getShader().setLocalMatrix(matrix)
        drawCircle(fixedZoomPoint.x, fixedZoomPoint.y, ZOOM_RADIUS, paint)
    }
}


Answer 4:

您可以通过使用自定义的ImageView实现它,创建你的包中的类CodesforMagnifierImageView.java。 你可以看到在各个类的代码CodesforMagnifier.java ,只需使用下面的代码在你的布局文件,而不是为ImageView的

<com.yourpackage.CodesforMagnifierImageView
     android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:src="@drawable/your image" />


文章来源: Android - How to circular zoom/magnify part of image?