您的位置:首页 > 其它

图片局部放大镜,可在大图上下左右移动并放大对应的区域

2015-08-16 11:54 706 查看
现实中使用放大镜可以放大对应的区域,软件中有时候也会用到放大镜功能,比如图片上某一点看不清楚,你不需要将整张图片都放大,只需要放大你想看到的部分,这个时候放大镜就派上用场了。

1.实现原理

如何实现放大镜的原理呢?一种方式我们可以采用将原图中的局部区域提取裁剪,然后在图片顶层的自定义控件上放大对应的倍数展示即可;另外一个种方式是将整图都放大相应的倍数,然后截取需要显示的区域,间接实现放大的效果,我使用的是第二种方法。

当然会涉及到平移,绘制边框的附加构件。

下面是实现的自定义类,具体注释见代码:

package com.example.zoompicview;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
* @Description TODO 图片放大镜控件实现
*/
public class ZoomToolView extends View {
private Path path;
private Matrix matrix;
private Paint paint;
private Bitmap bitmap;
private static final int RADIUS = 80;// 放大镜半径
private static final int FACTOR = 3; // 放大系数
private static final int STROKE = 4; // 附加线条宽度
private float currentX, currentY;

public ZoomToolView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

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

public ZoomToolView(Context context) {
super(context);
init();
}

private void init() {
path = new Path();
path.addCircle(RADIUS, RADIUS, RADIUS, Direction.CW);
matrix = new Matrix();
matrix.setScale(FACTOR, FACTOR);
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStrokeWidth(STROKE);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
}

public Bitmap getBitmap() {
return bitmap;
}

// 设置Bitmap
public void setBitmap(Bitmap bitmap) {
if (null != bitmap) {
this.bitmap = bitmap;
} else {
try {
throw new Exception("bitmap can't be null");
} catch (Exception e) {
e.printStackTrace();
}
}
}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (null == bitmap) {
return super.onTouchEvent(event);
}
currentX = event.getX();
currentY = event.getY();
// 控制不会移动出图片边界
if (currentX > bitmap.getWidth()) {
currentX = bitmap.getWidth();
} else if (currentX < 0) {
currentX = 0;
}
if (currentY > bitmap.getHeight()) {
currentY = bitmap.getHeight();
} else if (currentY < 0) {
currentY = 0;
}
invalidateView();
return true;
}

@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (null == bitmap) {
try {
throw new Exception("please setBitmap, bitmap can't be null");
} catch (Exception e) {
e.printStackTrace();
}
}
// 底图
canvas.drawBitmap(bitmap, 0, 0, null);
// 剪切
canvas.translate(currentX - RADIUS, currentY - RADIUS);
canvas.clipPath(path);

// 移动到path剪切部分显示
canvas.translate(RADIUS - currentX * FACTOR, RADIUS - currentY * FACTOR);
canvas.drawBitmap(bitmap, matrix, null);
// 反向平移并绘制十字和外边框
canvas.translate(currentX * FACTOR - RADIUS, currentY * FACTOR - RADIUS);
Path line = new Path();
line.moveTo(0, RADIUS);
line.lineTo(RADIUS * 2, RADIUS);
line.moveTo(RADIUS, 0);
line.lineTo(RADIUS, RADIUS * 2);
canvas.drawPath(line, paint);
canvas.drawCircle(RADIUS, RADIUS, RADIUS - STROKE, paint);
}

private void invalidateView() {
if (Looper.getMainLooper() == Looper.myLooper()) {
invalidate();
} else {
postInvalidate();
}
}

}


2.效果图



顶部的放大镜可以随着手指的移动而移动。

3.Demo 下载

点此下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: