Android加载大图——BitmapRegionDecoder(转)

 

BitmapRegionDecoder,从API10就引入了。如下图:

 
NPONRY0T35GE$13{254X8Z1.png

看官方文档的说明,这个类就是用来显示指定区域的图像,当原始图像大,你只需要部分图像时,BitmapRegionDecoder特别有用。

二、使用

 
J1_7H5)MI{M2PV{){{3V97V.png
最主要的就是BitmapRegionDecode.newInstance(...)获取一个对象,然后通过这个对象去调用decodeRegion(...)得到bitmap,最后就可以显示在屏幕上了。考虑到用户可以触摸移动图像,我们用手势控制器GestureDetector来控制图片显示的区域。
public class LargeImageView extends View implements GestureDetector.OnGestureListener {
private static final String TAG = "LargeImageView"; private BitmapRegionDecoder mDecoder; //绘制的区域
private volatile Rect mRect = new Rect(); private int mScaledTouchSlop; // 分别记录上次滑动的坐标
private int mLastX = 0;
private int mLastY = 0; //图片的宽度和高度
private int mImageWidth, mImageHeight;
//手势控制器
private GestureDetector mGestureDetector;
private BitmapFactory.Options options; public LargeImageView(Context context) {
super(context);
init(context, null);
} public LargeImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
} public LargeImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
} private void init(Context context, AttributeSet attrs) {
//设置显示图片的参数,如果对图片质量有要求,就选择ARGB_8888模式
options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565; mScaledTouchSlop = ViewConfiguration.get(getContext())
.getScaledTouchSlop();
Log.d(TAG, "sts:" + mScaledTouchSlop);
//初始化手势控制器
mGestureDetector = new GestureDetector(context, this); //获取图片的宽高
InputStream is = null;
try {
is = context.getResources().getAssets().open("timg.jpg");
//初始化BitmapRegionDecode,并用它来显示图片
mDecoder = BitmapRegionDecoder
.newInstance(is, false);
BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
// 设置为true则只获取图片的宽高等信息,不加载进内存
tmpOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, tmpOptions);
mImageWidth = tmpOptions.outWidth;
mImageHeight = tmpOptions.outHeight;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
} @Override
public boolean onTouchEvent(MotionEvent event) {
//把触摸事件交给手势控制器处理
return mGestureDetector.onTouchEvent(event);
} @Override
public boolean onDown(MotionEvent e) {
mLastX = (int) e.getRawX();
mLastY = (int) e.getRawY();
return true;
} @Override
public void onShowPress(MotionEvent e) { } @Override
public boolean onSingleTapUp(MotionEvent e) { return false;
} @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
int x = (int) e2.getRawX();
int y = (int) e2.getRawY();
move(x, y); return true;
} /**
* 移动的时候更新图片显示的区域
*
* @param x
* @param y
*/
private void move(int x, int y) {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
Log.d(TAG, "move, deltaX:" + deltaX + " deltaY:" + deltaY);
//如果图片宽度大于屏幕宽度
if (mImageWidth > getWidth()) {
//移动rect区域
mRect.offset(-deltaX, 0);
//检查是否到达图片最右端
if (mRect.right > mImageWidth) {
mRect.right = mImageWidth;
mRect.left = mImageWidth - getWidth();
} //检查左端
if (mRect.left < 0) {
mRect.left = 0;
mRect.right = getWidth();
} invalidate();
}
//如果图片高度大于屏幕高度
if (mImageHeight > getHeight()) {
mRect.offset(0, -deltaY); //是否到达最底部
if (mRect.bottom > mImageHeight) {
mRect.bottom = mImageHeight;
mRect.top = mImageHeight - getHeight();
} if (mRect.top < 0) {
mRect.top = 0;
mRect.bottom = getHeight();
}
//重绘
invalidate();
} mLastX = x;
mLastY = y;
} @Override
public void onLongPress(MotionEvent e) {
mLastX = (int) e.getRawX();
mLastY = (int) e.getRawY();
} @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int x = (int) e2.getRawX();
int y = (int) e2.getRawY();
move(x, y);
return true;
} @Override
protected void onDraw(Canvas canvas) {
//显示图片
Bitmap bm = mDecoder.decodeRegion(mRect, options);
canvas.drawBitmap(bm, 0, 0, null);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = getMeasuredWidth();
int height = getMeasuredHeight(); int imageWidth = mImageWidth;
int imageHeight = mImageHeight; //默认显示图片的中心区域,开发者可自行选择
mRect.left = imageWidth / 2 - width / 2;
mRect.top = imageHeight / 2 - height / 2;
mRect.right = mRect.left + width;
mRect.bottom = mRect.top + height; } }

最新文章

  1. 制作简单的2D物理引擎(一)&mdash;&mdash;动力学基础
  2. python的反射机制
  3. mvc、mvp、mvvm使用关系总结
  4. [LeetCode]题解(python):064-Minimum Path Sum
  5. redis主从 哨兵
  6. 说说关于php内置函数curl_init()
  7. 关于stringWithFormat: - 两段NSString如何合成一段
  8. 关于ASP.NET WebForm与ASP.NET MVC的比较
  9. 不依赖jstack的java 线程dump和死锁检查工具
  10. Spring Boot事务管理(上)
  11. 第一次实验: CC2530平台上电源管理与休眠
  12. consul的安装与使用
  13. 「POJ 1135」Domino Effect(dfs)
  14. [转帖] kubeadm搭建kubernetes集群
  15. eclipse代码提示javadoc背景为黑色框的解决办法
  16. JS数组的赋值
  17. mysql中enum类型
  18. Java如何用一行代码初始化ArrayList
  19. VS中C#连接SQLite数据库处理器架构“x86”不匹配的问题
  20. NYOJ 328 完全覆盖 (找规律)

热门文章

  1. Vue异步请求最佳实践
  2. stackstorm docker中配置ssh免密码登录方式
  3. 【转】bitbake 笔记
  4. java使用策略模式代替if/else
  5. TF_RNNCell
  6. Linux下python3的安装以及redis的使用
  7. 7.2 jmu-Java-06异常-02-使用异常机制处理异常输入 (5分)
  8. mysql中给查询结果添加序号列
  9. PHP类知识----面向对象在内存空间的分布情况
  10. python3爬虫--shell命令的使用和firefox firebug获取目标信息的xpath