图片局部放大镜,可在大图上下左右移动并放大对应的区域
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 下载
点此下载相关文章推荐
- 常用的视频剪辑软件
- android 相机图库调用以及裁剪
- nginx 常用配置说明
- Java NIO系列教程(四) Scatter/Gather
- android学习笔记1
- CodeForces 45C Dancing Lessons
- 暑假热身 A. GCC
- 把握linux内核设计思想(十三):内存管理之进程地址空间
- windows下编译libx264,libx265,libvpx
- 使用C语言求N的阶乘的方法
- 采用SharedPreference保存用户偏好参数设置
- Android SQLite 简单使用示例
- 泛函编程(37)-泛函Stream IO:通用的IO处理过程-Free Process
- 字符串生成器
- 泛函编程(37)-泛函Stream IO:通用的IO处理过程-Free Process
- leetcode - Reverse Words in a String
- junit基础学习之-多线程测试(6)
- android ViewPager实现App主界面Tab菜单页面切换和点击事件
- javascript中 try catch用法
- 机房收费系统之(模块使用)