BitmapRegionDecoder
Android加载大图——BitmapRegionDecoder(转)
BitmapRegionDecoder,从API10就引入了。如下图:

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

最主要的就是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;
}
}
BitmapRegionDecoder的更多相关文章
- Android 高清加载巨图方案 拒绝压缩图片
Android 高清加载巨图方案 拒绝压缩图片 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/49300989: 本文出自:[张 ...
- Android 高清加载巨图方案, 拒绝压缩图片
源地址:http://blog.csdn.net/lmj623565791/article/details/49300989 一.概述 距离上一篇博客有段时间没更新了,主要是最近有些私事导致的,那么就 ...
- Android Framework 其中A记录
一个简短的引论 以往的研究太偏应用层的功能,实现了,原则上不进入非常理解,现在,研究人员framework该框架层. 创纪录的 1.下载源代码,文件夹例如以下: 2.Android系统的层次例如以下: ...
- Android开发技巧——大图裁剪
本篇内容是接上篇<Android开发技巧--定制仿微信图片裁剪控件> 的,先简单介绍对上篇所封装的裁剪控件的使用,再详细说明如何使用它进行大图裁剪,包括对旋转图片的裁剪. 裁剪控件的简单使 ...
- 说一说关于破解支付宝AR红包的事
当朋友圈的你们才开始分享支付宝AR红包的消息的时候,我已经对它动了一二三四次歪脑筋了,虽然事实证明并不是那么顺利,至今我也只在电脑前识别出5个不知道在哪里的红包,其中一个还因为定位信息不符开不了. 昨 ...
- Android Framework 学习和需要学习的内容
1. 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework面存一些资料待有空查看. 2.Android系统的层次如下: 3.项目目录简单分析如下: 4.telphony ...
- android 自定义相机
老规矩,先上一下项目地址:GitHub:https://github.com/xiangzhihong/CameraDemo 方式: 调用Camera API 自定义相机 调用系统相机 由于需求不同, ...
- 年底Android面试整理(附答案)
面试,无非都是问上面这些问题(挺多的 - -!),聘请中高级的安卓开发会往深的去问,并且会问一延伸二.以下我先提出几点重点,是面试官基本必问的问题,请一定要去了解! 基础知识 – 四大组件(生命周期, ...
- Android&Java面试题大全—金九银十面试必备
声明本文由作者:Man不经心授权转载,转载请联系原文作者原文链接:https://www.jianshu.com/p/375ad14096b3, 类加载过程 Java 中类加载分为 3 个步骤:加载. ...
随机推荐
- Base64加密后有换行回车的解决办法
据RFC 822规定,每76个字符,还需要加上一个回车换行 有时就因为这些换行弄得出了问题,解决办法如下,替换所有换行和回车 String bTemp = Base64.encodeBase64Str ...
- python 文本相似度计算
参考:python文本相似度计算 原始语料格式:一个文件,一篇文章. #!/usr/bin/env python # -*- coding: UTF-8 -*- import jieba from g ...
- Linux(CentOS)下编译安装apache
Centos7.6系统 已经安装lnmp一键环境 想装个apache跑php7 (php7的安装以及与apache的交互在这里: https://www.cnblogs.com/lz0925/p/11 ...
- 内核模式构造-Semaphore构造(WaitLock)
internal sealed class SimpleWaitLock : IDisposable { //(信号量)允许多个线程并发访问一个资源 //如果所有线程以只读方式访问资源则是安全的 pr ...
- 生产者消费者问题--lock
# 代码: public class App { public static void main(String[] args) { Depot depot = new Depot(100); Prod ...
- Python往kafka生产消费数据
安装 kafka: pip install kafka-python 生产数据 from kafka import KafkaProducer import json ''' 生产者demo 向te ...
- MyBatis Generator 移除字段前缀
在table标签内添加 <columnRenamingRule searchString="wrc_" replaceString=""/> < ...
- kubernetes离线包安装教程
kubernetes离线包安装教程: 安装包中不包含docker,如没装docker 请先安装之yum install -y docker 1 2 3 1. master上: cd shell &am ...
- (六)监控磁盘IO
(1)被监控端配置 #vi /etc/zabbix/zabbix_agentd.conf UnsafeUserParameters= UserParameter=custom.vfs.dev.read ...
- 常见https,SSH协议和MD5加密方式分析
前言 https,SSH协议和MD5加密是前端可能会接触到的加密,所以我就将他们进行了一个归纳. 1.https 1.1原理 A.就是在http加入SSL层,是http安全的基础;B.htts协议是在 ...