【Android 内存优化】Bitmap 长图加载 ( BitmapRegionDecoder 简介 | BitmapRegionDecoder 使用流程 | 区域解码加载示例 )
文章目錄
- 一、BitmapRegionDecoder 簡介
- 二、圖片信息
- 三、BitmapRegionDecoder 對象創建
- 四、解碼圖像
- 五、圖像區域解碼示例
- 六、源碼及資源下載
一、BitmapRegionDecoder 簡介
官方文檔 API : BitmapRegionDecoder
BitmapRegionDecoder 簡介 :
① 主要作用 : BitmapRegionDecoder 可以從圖像中 解碼一個矩形區域 ;
② 適用場景 : 當一張圖片非常大 , 在手機中只需要顯示其中一部分內容 , BitmapRegionDecoder 非常有用 ;
③ 基本使用流程 : 先創建 , 后解碼 ;
- 流程 1 : 創建 BitmapRegionDecoder : 調用 newInstance 方法 , 創建 BitmapRegionDecoder 對象 ;
- 流程 2 : 解碼圖像區域內容 : 調用 decodeRegion 方法 , 獲取指定 Rect 矩形區域的解碼后的 Bitmap 對象 ;
二、圖片信息
將一張圖片存放在 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 ;
四、解碼圖像
函數原型 : 解碼 JPEG 或 PNG 中指定的矩形區域 ;
- 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 使用流程 | 区域解码加载示例 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【错误记录】GitHub 提交代码失败、
- 下一篇: 【Android 内存优化】自定义组件长