【问题标题】:Android ImageView Zooming EffectAndroid ImageView 缩放效果
【发布时间】:2015-07-29 20:28:47
【问题描述】:

目前我正在尝试开发一个应用程序,用户可以在其中放大图像。但是我需要制作镜头效果而不是捏缩放,这意味着当用户单击图像并将手指放在其上一段时间时,它会出现放大图像的圆圈。它看起来像这样:

我查看了下面提供的答案和链接并得到了这样的结果,但它不起作用:

public class MainActivity extends Activity implements OnTouchListener{
ImageView takenPhoto;
static PointF zoomPos;
Paint shaderPaint;
BitmapShader mShader;
BitmapShader shader;
Bitmap bmp;
Bitmap mutableBitmap;
static Matrix matrix;
Canvas canvas;
static Paint mPaint;
static boolean zooming;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        File file = new File(Environment.getExternalStorageDirectory() + "/Pictures/boxes.jpg");

        String fileString = file.getPath();


        takenPhoto = (ImageView) findViewById(R.id.imageView1);

        bmp = BitmapFactory.decodeFile(fileString);
        mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
        takenPhoto.setImageBitmap(mutableBitmap);

        matrix = new Matrix();
        mShader = new BitmapShader(mutableBitmap, TileMode.CLAMP, TileMode.CLAMP); 
        mPaint = new Paint();
        mPaint.setShader(mShader);
        takenPhoto.setOnTouchListener(this);
    }

    private static class ZoomView extends View {



        public ZoomView(Context context) {
            super(context);
        }


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

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





    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        return true;
    }


}

【问题讨论】:

标签: javascript android image zooming


【解决方案1】:

我的猜测是:

1- 您必须在图像视图上使用触摸侦听器
2- 你必须有一个画布(你可以在其中绘制缩放位图)

如果您还想实现 onDragListener 以在您将手指拖过图像时更新圆形缩放图像。

我想说看看这个链接:Android - How to circular zoom/magnify part of image?

【讨论】:

  • 嘿。我已经解决了您的答案,它非常有用。虽然我遇到了问题 - 当我使用来自链接中批准的答案的完全相同的代码时,什么也没有发生。请您检查一下代码好吗?我已经更新了问题。
  • 请检查并回复您
  • 对于用一根手指移动圆圈的问题,您必须在图像上使用 onDragListener 才能自行缩放,但效果会移动一个圆圈。要清除绘图,您应该调用 Canvas.drawColor()。此方法会将画布中的每个像素重新绘制为您想要的颜色。这将使圆圈消失。
  • onTouchListener 工作正常。所以添加 onDragListener 是没有意义的。当我使用 Canvas.drawColor(0) 或 canvas.drawColor(Color.TRANSPARENT) 没有任何反应 - 仍然有缩放点
  • 您尝试添加无效吗?
【解决方案2】:

在尝试解决这个特定问题好几天之后,感谢上面的答案和其他来源,我能够编写完整的工作代码。

为大家节省时间。复制粘贴并稍作修改以适应您的目标。

首先您需要编辑您的主要活动 - 我们将使用自定义 ImageView

 <your.package.name.ZoomView
    android:id="@+id/imageView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

然后我们将编辑 MainActivity.java。像 ImageView 一样使用 ZoomView

ImageView takenPhoto;
takenPhoto = (ZoomView) findViewById(R.id.imageView1);

之后,创建 ZoomView 类并粘贴:

public class ZoomView extends ImageView {

PointF zoomPos;
boolean zooming;
Matrix matrix;
BitmapShader mShader;
Paint mPaint;

public ZoomView(Context context) {
    super(context);
}

public ZoomView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public ZoomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
    zoomPos = new PointF();
    zoomPos.x = event.getX();
    zoomPos.y = event.getY();

    matrix = new Matrix();
    mShader = new BitmapShader(MainActivity.mutableBitmap, TileMode.CLAMP, TileMode.CLAMP);
    mPaint = new Paint();
    mPaint.setShader(mShader);

    int action = event.getAction(); 

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

    default: 
        break; 
    }
 return true;
}

@Override
protected void onDraw(@NonNull 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);
    }
}
}

现在你应该有工作放大效果了。

【讨论】:

  • 但圆圈将始终在您的手指下。如果您通过更改 zoomPos.x 和 zoomPos.y 来更改其位置,则位图将被放大到错误的位置。
【解决方案3】:

一种可能的解决方案是从显示图像的视图中抓取 Canvas 对象。您将需要使用各种motion events 更新画布。

在处理这些事件时,使用draw only a portion of the image 的功能。列出的方法是 Canvas 对象的一部分。至于参数:

Bitmap bitmap   //The image to zoom on
Rectangle src   //A rectangle defining the portion of the image to zoom in on
Rectangle dest  //A rectangle defining where in the View to draw the zoomed portion of your image. 
                //If the size of the rectangles is mismatched, it will zoom.
Paint paint     //The paint object necessary for drawing.

如果您有任何问题,请发表评论。编码愉快!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多