日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android 内存优化】自定义组件长图组件 ( 获取图像宽高 | 计算解码区域 | 设置图像解码属性 复用 像素格式 | 图像绘制 )

發(fā)布時(shí)間:2025/6/17 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 内存优化】自定义组件长图组件 ( 获取图像宽高 | 计算解码区域 | 设置图像解码属性 复用 像素格式 | 图像绘制 ) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 一、獲取圖像真實(shí)寬高
  • 二、計(jì)算解碼區(qū)域
  • 三、設(shè)置解碼參數(shù) 內(nèi)存復(fù)用 像素格式
  • 四、圖像繪制
  • 五、執(zhí)行效果
  • 六、源碼及資源下載



官方文檔 API : BitmapRegionDecoder


在【Android 內(nèi)存優(yōu)化】自定義組件長(zhǎng)圖組件 ( 自定義組件構(gòu)造方法 ) 基礎(chǔ)上繼續(xù)開發(fā) ;





一、獲取圖像真實(shí)寬高



顯示的圖像是一張長(zhǎng)圖 , 在該組件中 , 寬度肯定要完整顯示出來 , 解碼圖片的不同高度的數(shù)據(jù) ;

首先要測(cè)量圖片數(shù)據(jù)的真實(shí)寬高 , 然后根據(jù)圖像的寬高 , 與組件的寬高 , 以及要顯示的圖像位置 , 計(jì)算要解碼的圖像區(qū)域 ;


參考 【Android 內(nèi)存優(yōu)化】Bitmap 圖像尺寸縮小 ( 設(shè)置 Options 參數(shù) | inJustDecodeBounds | inSampleSize | 工具類實(shí)現(xiàn) ) 一、解碼圖片參數(shù) inJustDecodeBounds 章節(jié)內(nèi)容 , 有圖片解碼的詳細(xì)步驟 ;



1 . 圖片尺寸數(shù)據(jù)解碼 :


① 創(chuàng)建解碼選項(xiàng) : 創(chuàng)建 BitmapFactory.Options 對(duì)象 ;

② 設(shè)置解碼尺寸數(shù)據(jù) : 設(shè)置 BitmapFactory.Options 對(duì)象的 inJustDecodeBounds 為 true , 解碼圖像時(shí) , 不解碼圖像數(shù)據(jù) , 只獲取圖像的尺寸數(shù)據(jù) ;

③ 解碼圖像尺寸數(shù)據(jù) : 調(diào)用 BitmapFactory.decodeStream 方法 , 解碼圖片 , 圖片相關(guān)的尺寸數(shù)據(jù)保存到了 mOptions 選項(xiàng)中 ;

④ 獲取圖片尺寸 : mOptions.outWidth 是解碼出的圖像寬度 , mOptions.outHeight 是解碼出的圖像高度 ;



2 . 代碼示例 :

/*** Bitmap 解碼選項(xiàng)*/ private BitmapFactory.Options mOptions;/*** 圖片寬度*/ private int mImageWidth;/*** 圖片高度*/ private int mImageHeight;// ...// 解碼選項(xiàng) mOptions = new BitmapFactory.Options(); // 讀取圖片的尺寸數(shù)據(jù) mOptions.inJustDecodeBounds = true; // 解碼圖片 , 圖片相關(guān)的尺寸數(shù)據(jù)保存到了 mOptions 選項(xiàng)中 BitmapFactory.decodeStream(inputStream, null, mOptions); // 獲取圖片寬高 mImageWidth = mOptions.outWidth; mImageHeight = mOptions.outHeight;



二、計(jì)算解碼區(qū)域



1 . 顯示區(qū)域計(jì)算原則 : 這是一張長(zhǎng)圖 , 寬度完全顯示 , 高度顯示部分 ; 根據(jù)組件的寬高計(jì)算圖像顯示的區(qū)域 , 組件的寬高已知 , 寬高比例確定 ; 該寬高比例下 , 圖片顯示的區(qū)域也必須是該比例 ;



2 . 圖像寬高與組件寬高比例 : 加載的圖像高度寬度 , 與組件的高度寬度比例一致 ;


mViewWidthmViewHeight=加載的圖像寬度加載的圖像高度\dfrac{mViewWidth }{mViewHeight} = \dfrac{加載的圖像寬度}{加載的圖像高度}mViewHeightmViewWidth?=?


mViewWidth加載的圖像寬度=mViewHeight加載的圖像高度\dfrac{mViewWidth }{加載的圖像寬度} = \dfrac{mViewHeight }{加載的圖像高度}mViewWidth?=mViewHeight?



3 . 縮放因子 : 由于寬度必須填充慢組件寬度 , 這里需要縮放圖片 , 高分辨率手機(jī)需要縮小圖片 , 低分辨率手機(jī)需要放大圖片 ;

縮放因子=mViewWidth加載的圖像寬度縮放因子 = \dfrac{mViewWidth}{加載的圖像寬度 }=mViewWidth?



4 . 計(jì)算區(qū)域高度 : 圖像截取的寬度已知 , 組件的寬高已知 , 計(jì)算圖像截取的高度 :

mViewWidth加載的圖像寬度=mViewHeight加載的圖像高度=mViewHeight×加載的圖像寬度mViewWidth=mViewHeight縮放因子\begin{array}{lcl} \dfrac{mViewWidth }{加載的圖像寬度} &=& \dfrac{mViewHeight }{加載的圖像高度} \\\\ &=& \dfrac{mViewHeight \times 加載的圖像寬度}{mViewWidth} \\\\ &=& \dfrac{mViewHeight }{縮放因子} \end{array}mViewWidth??===?mViewHeight?mViewWidthmViewHeight×?mViewHeight??



5 . 代碼示例 : 在 onMeasure 方法中 , 獲取最新測(cè)量出來的組件寬高 , 根據(jù)以上公式 , 計(jì)算出要解碼圖像的寬高 ;

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);// 獲取測(cè)量的自定義 View 組件寬高mViewWidth = getMeasuredWidth();mViewHeight = getMeasuredHeight();// 根據(jù)組件的寬高 , 確定要加載的圖像的寬高if(mBitmapRegionDecoder != null){mRect.left = 0;mRect.top = 0;// 繪制的寬度就是圖像的寬度mRect.right = mImageWidth;// 根據(jù)圖像寬度 和 組件寬度 , 計(jì)算出縮放比例// 組件寬度 / 圖像寬度 = 縮放因子mScale = (float)mViewWidth / (float)mImageWidth;/*加載的圖像高度寬度 , 與組件的高度寬度比例一致mViewWidth / 加載的圖像寬度 = mViewHeight / 加載的圖像高度此處加載的圖像寬度就是實(shí)際的寬度加載的圖像高度 = mViewHeight / ( mViewWidth / 加載的圖像寬度 )mViewWidth / 加載的圖像寬度 就是縮放因子加載的圖像高度 = mViewHeight / 縮放因子*/// 根據(jù)縮放因子計(jì)算解碼高度mRect.bottom = (int) (mViewHeight / mScale);}}



三、設(shè)置解碼參數(shù) 內(nèi)存復(fù)用 像素格式



設(shè)置圖像解碼參數(shù) :


① 關(guān)閉尺寸解碼 : 之前解碼圖像尺寸 , 將 BitmapFactory.Options 的 inJustDecodeBounds 屬性設(shè)置為了 true , 現(xiàn)在要開始解碼圖像數(shù)據(jù)了 , 需要關(guān)閉該選項(xiàng) , 設(shè)置為 false ;

② 設(shè)置像素格式 : 如果不需要顯示透明度 , 就設(shè)置 BitmapFactory.Options 的 inPreferredConfig 像素格式為 Bitmap.Config.RGB_565 , 該像素格式每個(gè)像素占 2 字節(jié)內(nèi)存 ;

③ 設(shè)置可變 : 這是內(nèi)存復(fù)用生效的前提 , 設(shè)置 inMutable 為 true ;

④ 設(shè)置復(fù)用內(nèi)存的 Bitmap 對(duì)象 : 每次解碼操作前都要設(shè)置一次 , 解碼時(shí)會(huì)復(fù)用該 Bitmap 中的內(nèi)存 ;



2 . 代碼示例 :

/*** Bitmap 解碼選項(xiàng)*/ private BitmapFactory.Options mOptions;// ... // 設(shè)置 Bitmap 內(nèi)存復(fù)用 mOptions.inMutable = true; // 設(shè)置可變 // 內(nèi)存復(fù)用 mOptions.inBitmap = mBitmap; mOptions.inPreferredConfig = Bitmap.Config.RGB_565; // 設(shè)置像素格式 RGB 565 mOptions.inJustDecodeBounds = false; // 讀取完畢之后, 就需要解析實(shí)際的 Bitmap 圖像數(shù)據(jù)了



四、圖像繪制



1 . 圖像繪制 :


① 設(shè)置圖像區(qū)域解碼器 : 在為自定義組件設(shè)置圖片時(shí) , 設(shè)置區(qū)域解碼器 , 因?yàn)橐O(shè)置區(qū)域解碼的數(shù)據(jù)源 , 因此必須在用戶設(shè)置圖片時(shí) , 才可以創(chuàng)建區(qū)域解碼器 ;

② 設(shè)置內(nèi)存復(fù)用 : 每次解碼時(shí) , 都要設(shè)置一下內(nèi)存復(fù)用的 Bitmap 對(duì)象 ; mOptions.inBitmap = mBitmap;

③ 解碼圖片 : 調(diào)用區(qū)域解碼器的 mBitmapRegionDecoder.decodeRegion 方法 , 解碼圖片的特定區(qū)域 ;

④ 設(shè)置圖片縮放 : 使用 Matrix 進(jìn)行圖像縮放 ; 圖像與自定義組件的尺寸不同 , 因此需要將解碼區(qū)域完全填充到自定義組件中顯示 ;

⑤ 圖像繪制 : 調(diào)用 canvas.drawBitmap 繪制圖像 , 如果需要縮放 , 傳入 Matrix 參數(shù) ;



2 . 代碼示例 :

/*** 圖像區(qū)域解碼器*/private BitmapRegionDecoder mBitmapRegionDecoder;// .../*** 設(shè)置顯示的圖片* @param inputStream*/public void setImage(InputStream inputStream){// ...try {// Bitmap 區(qū)域解碼器mBitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);} catch (IOException e) {e.printStackTrace();}// 設(shè)置圖片完畢后 , 刷新自定義組件requestLayout();}// ...@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if(mBitmapRegionDecoder == null) return;// 內(nèi)存復(fù)用mOptions.inBitmap = mBitmap;// 解碼圖片mBitmap = mBitmapRegionDecoder.decodeRegion(mRect, mOptions);// 設(shè)置繪制的圖像縮放 , x 軸和 y 軸都在 Bitmap 大小的區(qū)域基礎(chǔ)上 , 縮放 mScale 倍Matrix matrix = new Matrix();matrix.setScale(mScale, mScale);canvas.drawBitmap(mBitmap, matrix, null);}



五、執(zhí)行效果



豎屏效果 :

橫屏效果 :





六、源碼及資源下載



源碼及資源下載地址 :

  • ① GitHub 工程地址 : Long_Graph_Loading

  • ② LongImageView.java 主界面代碼地址 : LongImageView.java , 這是上述示自定義組件代碼 ;

總結(jié)

以上是生活随笔為你收集整理的【Android 内存优化】自定义组件长图组件 ( 获取图像宽高 | 计算解码区域 | 设置图像解码属性 复用 像素格式 | 图像绘制 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。