Android - How to circular zoom/magnify part of image?

前端 未结 4 2065
青春惊慌失措
青春惊慌失措 2020-12-13 07:06

I am trying to allow the user to touch the image and then basically a cirular magnifier will show that will allow the user to better select a certain area on the image. Whe

相关标签:
4条回答
  • 2020-12-13 07:29

    Some people asked for a fixed place magnifier position, I experimented it and came up with the solution:

    // 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)
        }
    }
    
    0 讨论(0)
  • 2020-12-13 07:37

    The best way to revert any changes made to the image will be to reload the image from the source file. Or alternatively, keep the a copy original matrix variable before transformations begun, during MotionEvent.ACTION_UP load the original matrix.

    0 讨论(0)
  • 2020-12-13 07:42

    Adapting your code, I was able to get the following approach working.

    In the onTouch function, set a global point for determining where the user has touched, and set a boolean to indicate whether zooming is currently active or not:

    @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; 
    }
    

    Then, in the onDraw method, you use your code for drawing the zoomed in portion:

    @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);
        }
    }
    

    Note that for the shader, I used a bitmap shader as described here, which was created with:

    mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
    mShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
    
    mPaint = new Paint();
    mPaint.setShader(mShader);
    
    0 讨论(0)
  • 2020-12-13 07:49

    You can implement it by using a custom imageview ,Create a class CodesforMagnifierImageView.java in your package. You can see the code for respective class at CodesforMagnifier.java and simply use the following code in your layout file instead for the imageview

    <com.yourpackage.CodesforMagnifierImageView
         android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:src="@drawable/your image" />
    
    0 讨论(0)
提交回复
热议问题