【Android 内存优化】Bitmap 长图加载 ( BitmapRegionDecoder 简介 | BitmapRegionDecoder 使用流程 | 区域解码加载示例 )
文章目录
- 一、BitmapRegionDecoder 简介
- 二、图片信息
- 三、BitmapRegionDecoder 对象创建
- 四、解码图像
- 五、图像区域解码示例
- 六、源码及资源下载
一、BitmapRegionDecoder 简介
官方文档 API : BitmapRegionDecoder
BitmapRegionDecoder 简介 :
① 主要作用 : BitmapRegionDecoder 可以从图像中 解码一个矩形区域 ;
② 适用场景 : 当一张图片非常大 , 在手机中只需要显示其中一部分内容 , BitmapRegionDecoder 非常有用 ;
③ 基本使用流程 : 先创建 , 后解码 ;
- 流程 1 : 创建 BitmapRegionDecoder : 调用 newInstance 方法 , 创建 BitmapRegionDecoder 对象 ;
// 创建 BitmapRegionDecoder 对象方法
static BitmapRegionDecoder newInstance(InputStream is, boolean isShareable)
static BitmapRegionDecoder newInstance(FileDescriptor fd, boolean isShareable)
static BitmapRegionDecoder newInstance(String pathName, boolean isShareable)
static BitmapRegionDecoder newInstance(byte[] data, int offset, int length, boolean isShareable)
- 流程 2 : 解码图像区域内容 : 调用 decodeRegion 方法 , 获取指定 Rect 矩形区域的解码后的 Bitmap 对象 ;
Bitmap decodeRegion(Rect rect, BitmapFactory.Options options)
二、图片信息
将一张图片存放在 assets 目录下 , 图片尺寸为 938 x 7561 , 这是 BitmapRegionDecoder 的文档截图 ;
该图片如果按照默认的 ARGB_8888 格式加载到内存中 , 会占用 28,368,872 字节的内存 , 大约 27 MB ;
内存大小计算过程如下 :
938×7561×4=28,368,872938 \times 7561 \times 4 = 28,368,872938×7561×4=28,368,872
三、BitmapRegionDecoder 对象创建
1 . BitmapRegionDecoder 对象创建 : 调用 newInstance 方法创建该对象 ;
① 函数作用 : 根据输入流创建 BitmapRegionDecoder 对象 ;
② 输入流的数据位置 : 输入流的当前读取位置就是在之前读取的的解码数据的后面一个字节位置 ;
③ 支持的图像格式 : 目前图像区域解码对象只支持 JPEG 和 PNG 两种图像格式 ;
2 . 函数原型 :
InputStream is 参数 : 图片的输入流 ;
boolean isShareable 参数 : 是否共享输入流 ; 如果设置了共享为 true , 如果将该输入流关闭 , 假如 BitmapRegionDecoder 对象中也在使用该输入流 , 那么关闭以后 , BitmapRegionDecoder 对象也无法使用该输入流了 ; 如果设置该参数为 false , 那么关闭该输入流 , 不影响 BitmapRegionDecoder 对象使用 , 一般都是该区域解码对象需要长时间使用 , 此处都要设置成 false ;
public static BitmapRegionDecoder newInstance(InputStream is,boolean isShareable) throws IOException {// 当前的输入流是 AssetInputStream 输入流的情况if (is instanceof AssetManager.AssetInputStream) {return nativeNewInstance(((AssetManager.AssetInputStream) is).getNativeAsset(),isShareable);} else {// 当前的输入流是文件输入流// 传入临时缓存到 Native 代码中 ; // 创建一个足够大的临时缓存区 , 这样可以减少 is.read 方法的回调次数 ; // 应该避免 is.read 回调次数太多 , 同时每次读取很少数据的情况 ; byte [] tempStorage = new byte[16 * 1024];return nativeNewInstance(is, tempStorage, isShareable);}}
四、解码图像
函数原型 : 解码 JPEG 或 PNG 中指定的矩形区域 ;
- Rect rect 参数 : 要解码的矩形区域 ;
- BitmapFactory.Options options 参数 : 解码选项 ;
public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options)
五、图像区域解码示例
1 . 主界面代码 : 先创建 BitmapRegionDecoder 对象 , 然后调用该对象的 decodeRegion 方法 , 进行图像剪切 ;
package kim.hsl.lgl;import android.graphics.Bitmap;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import java.io.IOException;
import java.io.InputStream;public class MainActivity extends AppCompatActivity {static {System.loadLibrary("native-lib");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv = findViewById(R.id.sample_text);tv.setText(stringFromJNI());// 显示剪切后的正方形图像showImage();}private void showImage(){InputStream inputStream = null;try {// 获取 Assets 文件的输入流inputStream = getAssets().open("bitmap_region_decoder.png");/*函数原型 :public static BitmapRegionDecoder newInstance(InputStream is,boolean isShareable) throws IOException {InputStream is 参数 : 图片的输入流boolean isShareable 参数 : 是否共享输入流如果设置了共享为 true , 如果将该输入流关闭 ,假如 BitmapRegionDecoder 对象中也在使用该输入流 ,那么关闭以后 , BitmapRegionDecoder 对象也无法使用该输入流了 ;如果设置该参数为 false , 那么关闭该输入流 , 不影响 BitmapRegionDecoder 对象使用 ,一般都是该区域解码对象需要长时间使用 , 此处都要设置成 false ;*/BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);/*解码图片这里解析前面的一部分图片*/Bitmap bitmap = bitmapRegionDecoder.decodeRegion(new Rect(0, 0, 938, 938), //解码区域null); //解码选项 BitmapFactory.Options 类型ImageView imageView = findViewById(R.id.imageView);imageView.setImageBitmap(bitmap);} catch (IOException e) {e.printStackTrace();} finally {if(inputStream != null){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}}public native String stringFromJNI();
}
2 . 布局文件 : 在布局中放置一个正方形的 ImageView , 显示剪切后的 938 x 938 大小的 Bitmap 图片 ;
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ImageViewandroid:id="@+id/imageView"android:layout_width="match_parent"android:layout_height="0dip"android:scaleType="fitXY"app:layout_constraintDimensionRatio="1:1"app:layout_constraintVertical_bias="0"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/sample_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>
3 . 执行效果 : 正方形的 ImageView , 显示从 938 x 7561 大小的图片上剪切下来的 938 x 938 大小的图片 , 效果如下 ;
六、源码及资源下载
源码及资源下载地址 :
① GitHub 工程地址 : Long_Graph_Loading
② MainActivity.java 主界面代码地址 : MainActivity.java , 这是上述示例代码中的主界面代码 ;
【Android 内存优化】Bitmap 长图加载 ( BitmapRegionDecoder 简介 | BitmapRegionDecoder 使用流程 | 区域解码加载示例 )相关推荐
- 【Android 内存优化】自定义组件长图组件 ( 长图滚动区域解码 | 手势识别 GestureDetector | 滑动计算类 Scroller | 代码示例 )
文章目录 一.GestureDetector 创建与设置 二.GestureDetector 触摸事件传递 三.触摸滑动操作 四.惯性滑动操作 五.长图滑动组件代码示例 六.运行效果 七.源码及资源下 ...
- 【Android 内存优化】自定义组件长图组件 ( 获取图像宽高 | 计算解码区域 | 设置图像解码属性 复用 像素格式 | 图像绘制 )
文章目录 一.获取图像真实宽高 二.计算解码区域 三.设置解码参数 内存复用 像素格式 四.图像绘制 五.执行效果 六.源码及资源下载 官方文档 API : BitmapRegionDecoder 在 ...
- 【Android 内存优化】Bitmap 硬盘缓存 ( Google 官方 Bitmap 示例 | DiskLruCache 开源库 | 代码示例 )
文章目录 一.Google 官方 Bitmap 相关示例参考 二.磁盘缓存类 DiskLruCache 三.磁盘缓存初始化 四.存储数据到磁盘缓存中 五.从磁盘缓存中读取数据 六. Android 1 ...
- 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 内存复用 | 弱引用 | 引用队列 | 针对不同 Android 版本开发不同的 Bitmap 复用策略 | 工具类代码 )
文章目录 一.Bitmap 复用池 二.弱引用 Bitmap 内存释放 三.从 Bitmap 复用池中获取对应可以被复用的 Bitmap 对象 1.Android 2.3.3(API 级别 10)及以 ...
- 【Android 内存优化】Bitmap 图像尺寸缩小 ( 考虑像素密度、针对从不同像素密度资源中解码对应的 Bitmap 对象 | inDensity | inTargetDensity )
文章目录 一.像素密度对解码图片的影响 二.不考虑像素密度会导致图片缩小尺寸不准确 三.DisplayMetrics 源码阅读.研究手机资源获取规则 四.像素密度参数设置取值 ( inDensity ...
- 【Android 内存优化】Bitmap 内存占用计算 ( Bitmap 图片内存占用分析 | Bitmap 内存占用计算 | Bitmap 不同像素密度间的转换 )
文章目录 一.Bitmap 内存占用 二.Bitmap 内存占用计算示例 三.Bitmap 内存占用与像素密度 四.Bitmap 内存占用与像素密度示例 一.Bitmap 内存占用 在 Android ...
- 【Android 内存优化】Android 工程中使用 libjpeg-turbo 压缩图片 ( JNI 传递 Bitmap | 获取位图信息 | 获取图像数据 | 图像数据过滤 | 释放资源 )
文章目录 一.Bitmap 图像数据处理 二.Java 层 Bitmap 对象转为 JNI 层 bitmap 对象 三.获取 bitmap 中的图像数据 四.过滤 bitmap 中的图像数据 ( 获取 ...
- Android 系统性能优化(39)---Android内存优化之三:打开MAT中的Bitmap原图
Android内存优化之三:打开MAT中的Bitmap原图 在使用MAT查看应用程序内存使用情况的时候,我们经常会碰到Bitmap对象以及BitmapDrawable$BitmapState对象,而且 ...
- 深入探索Android内存优化
前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~. 本篇是Android内存优化的进阶篇,难度会比较大,建议对内存优化不是非常熟悉的前仔细看看在 ...
最新文章
- 【校招面试 之 C/C++】第16题 C++ new和delete的实现原理
- r语言如何写入一个excel_R语言如何进行聚类分析?
- 【Java】7.3 基本类 7.4 Java 8 的日期、时间类
- Leetcode题库 172.阶乘后的零(C实现)
- 轻松部署IE7(下),SMS2003系列之六
- 安全是什么意思_屈老师小班安全教案《安全标志》
- CDialog::OnOk()作用
- python动态爱心曲线_使用matplotlib动态刷新指定曲线实例
- oracle判断日期字符串格式,如何测试日期格式字符串是否为Oracle中的有效日期格式字符串...
- 将hta包装为exe发布
- 学生成绩管理系统(C语言实现)
- Java之函数式接口
- 爆干3天整理出来,408考研计算机网络复习笔记(更新中)
- 计算机模拟求解流体力学方程,计算流体力学CFD及其应用
- CSMA/CA精辟总结
- 手机USB共享电脑宽带的尝试过程,从失败到成功
- 理财线下转账交易SQL加合计行
- 洛谷 [P3975 [TJOI2015]弦论
- python 进阶 【封装】 适合小白入门
- linux的nslookup命令,Linux nslookup命令
热门文章
- [Ubuntu] 如何在Ubuntu11.04将PHP5.3降级到PHP5.2
- 微软在你的计算机里隐藏的秘密
- vue 项目中 点击回车键 自动登录
- 【loj6342】跳一跳 期望dp
- 模态框在IE下的问题,即position:fixed在IE下不兼容的处理方式
- linux动态链接库---一篇讲尽
- xcode编译Undefined symbols for architecture i386问题解决
- 从门禁系统的使用体验看良好的交互设计原则
- 杭电多校(五)2019.08.05--暑假集训
- Linux之nginx入门