You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BitmapRegionDecoder can be used to decode a rectangle region from an image.
BitmapRegionDecoder is particularly useful when an original image is large and
you only need parts of the image
Activity
rainbow7 commentedon Aug 27, 2019
BitmapRegionDecoder
它的官方解释
很直白,加载一张图片的一部分。
使用也很简单。rect是一个显示区域,options是图片的设置项。这样就可以显示一张大图的的部分了。显示不同的区域,根据手势调整rect的区域即可。
firehell commentedon Aug 28, 2019
https://www.jianshu.com/p/116e05dfd66b
参考这个文章,一些想法
1.用浏览器加载的方法,从上到下一点一点加载,这样的好处是图片清晰度比较高
2.先加载一张缩略图占位,然后压缩整个图片,减少图片的像素加载出图片,会快一些但不够清晰
//尺寸压缩(通过缩放图片像素来减少图片占用内存大小)
`public static void sizeCompress(Bitmap bmp, File file) {
// 尺寸压缩倍数,值越大,图片尺寸越小
int ratio = 8;
// 压缩Bitmap到对应尺寸
Bitmap result = Bitmap.createBitmap(bmp.getWidth() / ratio, bmp.getHeight() / ratio, Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Rect rect = new Rect(0, 0, bmp.getWidth() / ratio, bmp.getHeight() / ratio);
canvas.drawBitmap(bmp, null, rect, null);
chinwetang commentedon Aug 28, 2019
加载优化的就是Http协议中的Range / Accept-Range ,他可以指定获取body的一部分,从而达到分块加载图片的效果;
内存优化的方向是,我屏幕只有这么大,那我就只加载跟屏幕一样的Bitmap就好了,超出屏幕外面的就没必要加到内存里面增加负担;
根据手势滑动每次重新计算mRect去获取部分bitmap绘制到屏幕上。
skylarliuu commentedon Aug 28, 2019
(谢谢上面同学的回答)
加载大长图可以使用 压缩或局部加载的方法。
压缩可以使用BitmapFactory类的相关方法,获取到图片的原始大小后,再计算图片压缩比,最后压缩图片后再显示。不过压缩就会降低图片的清晰度,如果要按原图加载图片,可以用BitmapRegionDecoder实现图片局部加载。
BitmapRegionDecoder可以用来显示图片指定的一个矩形区域。通过自定义View重写onTouchEvent()判断手势滑动位置,从而改变矩形区域的位置。
如果是加载网络大图片,还可以分块请求数据,让图片更快地显示出来。
(分享鸿洋的一篇博客:Android 高清加载巨图方案 拒绝压缩图片)
zhengjunke commentedon Aug 28, 2019
参考简书资料:https://www.jianshu.com/p/4640764bfbc6
图片太大,进行压缩处理:
BitmapFactory这个类就提供了多个解析方法(decodeResource、decodeStream、decodeFile等)用于创建Bitmap。我们可以根据图片的来源来选择解析方法。比如如果图片来源于网络,就可以使用decodeStream方法;如果是sd卡里面的图片,就可以选择decodeFile方法;如果是资源文件里面的图片,就可以使用decodeResource方法等。
BitmapFactory为这些方法都提供了一个可选的参数BitmapFactory.Options,用来辅助我们解析图片。这个参数有一个属性inSampleSize,这个属性可以帮助我们来进行图片的压缩。
如果不进行压缩处理,图片超出屏幕显示范围,进行局部加载处理:
BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
bitmapRegionDecoder.decodeRegion(rect, options);
参数一是一个rect,控制显示区域,参数二是BitmapFactory.Options,你可以控制图片的inSampleSize,inPreferredConfig等。
pioneerz commentedon Aug 28, 2019
1.对图片进行压缩处理
这种方案虽然也能够显示,但是不能够保证图片的清晰度。
2.局部展示:
这种方案是加载图片的局部,如果要观察其余部分,可以通过增加手势操作或者触摸事件。
chengying1216 commentedon Aug 29, 2019
https://www.jianshu.com/p/4640764bfbc6
SeniorDoctorHui commentedon Aug 29, 2019
对于加载大长图主要有以下一些路径:
1,对于加载网络的图片,如果只是作为缩略图展示的话,可以下载该图片的缩略图来展示,以提高加载速度和省流量的目的。点击详情图片时,才去加载原图。
2,就是使用上面各位同学说的BitmapRegionDecoder这个类来展示局部图片,根据可见区域来加载图片,从而避免oom的问题。但是该类只是Android为我们提供的基本API,实际使用中,你会发现如果在onDraw方法中绘制bitmap对象会占用主线程资源,导致丢帧而造成卡顿的现象。除此之外还需要考虑快速滑动而造成bitmap大量创建和大量回收而生成的抖动问题。而且如果要加载长图,还要有放大缩小的功能,这些也需要我们自己实现。
3,使用SubsamplingScaleImageView框架来加载长图,该框架底层就是使用BitmapRegionDecoder来加载局部图片的,该框架提供了缩放和触摸等手势的功能。该框架为了解决滑动卡顿的问题,对于move事件进行了优化,不会直接加载清晰度高的图片,而是对于原解码率的图片进行scale放大,直到up事件发生后,才会在后台加载相应解码率的图片,生成对应的bitmap,再进行相应的更新。因此滑动时,我们先会看到模糊的图片,然后才能看到清晰的图片。它的缺点是不能直接加载网络的图片,要把网络的图片下载到本地才能加载。
4,使用SketchImageView来加载长图,底层也是BitmapRegionDecoder实现的。这是一套很完整的图片加载框架,对于大图的分块加载,缩放手势,缓存复用缓存回收应有尽有,支持加载网络链接的大图。是一套很不错的加载大图的商业级方案,具体介绍可以看https://github.com/panpf/sketch