Android ImageView缩放效果
Android ImageView Zooming Effect
目前我正在尝试开发一个应用程序,用户可以在其中放大图像。但是我需要制作镜头效果而不是捏缩放,这意味着当用户单击图像并将手指放在它上面一段时间时,它的正上方会出现带有放大图像的圆圈。它看起来像这样:
我查看了下面提供的答案和链接并得到了这样的答案,但它不起作用:
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;
}
}
嗯,我的猜测是:
1- 您必须在图像视图上使用触摸侦听器
2- 你必须有一个 canvas (你绘制缩放位图的地方)
如果您还想实现 onDragListener 以在您将手指拖过图像时更新圆形缩放图像。
我会说看看这个 link : Android - How to circular zoom/magnify part of image?
一种可能的解决方案是从显示图像的视图中抓取 Canvas 对象。您将需要使用各种 motion events 更新 Canvas。
在处理这些事件时,使用 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.
如有任何问题,请发表评论。编码愉快!
经过几天尝试解决这个特定问题后,由于上面的答案和其他来源,我能够编写完整的工作代码。
为了节省大家的时间,就在这里。复制粘贴并对其进行一些编辑以符合您的目标。
首先你需要编辑你的主要 activity - 我们将使用自定义 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 class 并粘贴:
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);
}
}
}
现在你应该有放大效果了。
目前我正在尝试开发一个应用程序,用户可以在其中放大图像。但是我需要制作镜头效果而不是捏缩放,这意味着当用户单击图像并将手指放在它上面一段时间时,它的正上方会出现带有放大图像的圆圈。它看起来像这样:
我查看了下面提供的答案和链接并得到了这样的答案,但它不起作用:
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;
}
}
嗯,我的猜测是:
1- 您必须在图像视图上使用触摸侦听器
2- 你必须有一个 canvas (你绘制缩放位图的地方)
如果您还想实现 onDragListener 以在您将手指拖过图像时更新圆形缩放图像。
我会说看看这个 link : Android - How to circular zoom/magnify part of image?
一种可能的解决方案是从显示图像的视图中抓取 Canvas 对象。您将需要使用各种 motion events 更新 Canvas。
在处理这些事件时,使用 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.
如有任何问题,请发表评论。编码愉快!
经过几天尝试解决这个特定问题后,由于上面的答案和其他来源,我能够编写完整的工作代码。
为了节省大家的时间,就在这里。复制粘贴并对其进行一些编辑以符合您的目标。
首先你需要编辑你的主要 activity - 我们将使用自定义 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 class 并粘贴:
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);
}
}
}
现在你应该有放大效果了。