亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

【Android Developers Training】 56. 更效率地

系統 1812 0

注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。

原文鏈接: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html


圖像的的形狀和尺寸千變萬化。在很多情況下它們比一般的應用UI所需要的尺寸更大一些。例如,在系統圖庫這個應用中,顯示的照片是用你的Android設備拍攝的照片,它們比起屏幕的尺寸來說要大多了。

假設你現在只有有限的內存,那么在理想情況下你希望在內存中加載分辨率更小的圖片。這個低分辨率版本的圖片需要和將它顯示出來的UI組件的尺寸相匹配。一個過高分辨率的圖片并不會帶來什么改善視覺體驗,反而會消耗大量的內存空間,并且因為在運行時需要調整圖片的尺度而導致應用性能表現欠佳。

這節課將帶你學習通過加載一個大位圖的減采樣版本的圖片到內存中,以此來防止應用的內存空間耗盡。


一). 讀取位圖的尺寸和類型

BitmapFactory 類提供了一些解碼方法( decodeByteArray() decodeFile() decodeResource() 等)來為不同的源創建位圖。應該基于你的圖像數據源選擇最合適的解碼方法。這些方法嘗試為構建好的圖像分配空間,因此它很容易導致 OutOfMemory 異常。每種解碼方法都有額外的參數選項可以讓你通過 BitmapFactory.Options 類指定解碼選項。在解碼時,將 inJustDecodeBounds 屬性設置為 true 可以防止內存溢出,如果不設置 outWidth outHeight outMimeType 的話,那么就會對該圖像對象返回 null 。這個技術逼迫你在構造(和分配內存時)之前先讀取圖像的尺寸和圖像數據的類型。

      BitmapFactory.Options options = 
      
        new
      
      
         BitmapFactory.Options();

options.inJustDecodeBounds 
      
      = 
      
        true
      
      
        ;

BitmapFactory.decodeResource(getResources(), R.id.myimage, options);


      
      
        int
      
       imageHeight =
      
         options.outHeight;


      
      
        int
      
       imageWidth =
      
         options.outWidth;

String imageType 
      
      = options.outMimeType;
    

為了避免 OutOfMemory 異常,在解碼圖像之前檢查它的尺寸,除非你完全相信提供給你圖像的源會給你尺寸正好合適的圖像數據,它能夠符合有限的存儲空間。


二). 加載一個縮小版本的圖像到存儲當中

現在這個圖像的尺寸已經知道了,它們可以被用來這個完整的圖片能否被加載到內存中,或者一個減采樣的版本是否要被加載。下面是一些要考慮的因素:

  • 估計一下如果加載完整圖片的話內存的使用情況。
  • 結合應用中其他內存的需求,決定這幅圖片能使用多少大的內存空間。
  • 這個圖片要被加載到的 ImageView 或UI組建的尺寸。
  • 當前設備的屏幕尺寸和分辨率。

例如,如果要把一幅 1024x768的 圖片加載到一個大小為128x96大小的 ImageView ,顯然這么做事不值得的。

為了告訴解碼器對圖像進行減采樣,加載一個更小的版本到內存中,在你的 BitmapFactory.Options 對象中將 inSampleSize 設置為 true 。例如,一個分辨率為 2048x1536的 圖像加上 inSampleSize 設置為4的選項后,會產生一幅大小為 512x384的圖。將它加載進系統需要使用0.75MB而不是全尺寸圖像所需要的12MB(假定位圖配置為 ARGB_8888 )。下面的方法用來計算一個圖像的減采樣版本(如果圖像過大的話):

      
        public
      
      
        static
      
      
        int
      
      
         calculateInSampleSize(

            BitmapFactory.Options options, 
      
      
        int
      
       reqWidth, 
      
        int
      
      
         reqHeight) {

    
      
      
        //
      
      
         Raw height and width of image
      
      
        final
      
      
        int
      
       height =
      
         options.outHeight;

    
      
      
        final
      
      
        int
      
       width =
      
         options.outWidth;

    
      
      
        int
      
       inSampleSize = 1
      
        ;



    
      
      
        if
      
       (height > reqHeight || width >
      
         reqWidth) {



        
      
      
        final
      
      
        int
      
       halfHeight = height / 2
      
        ;

        
      
      
        final
      
      
        int
      
       halfWidth = width / 2
      
        ;



        
      
      
        //
      
      
         Calculate the largest inSampleSize value that is a power of 2 and keeps both

        
      
      
        //
      
      
         height and width larger than the requested height and width.
      
      
        while
      
       ((halfHeight / inSampleSize) >
      
         reqHeight

                
      
      && (halfWidth / inSampleSize) >
      
         reqWidth) {

            inSampleSize 
      
      *= 2
      
        ;

        }

    }



    
      
      
        return
      
      
         inSampleSize;

}
      
    

Note:

從上述代碼可以看到,在計算減采樣因數時,以2為級數增加, 選擇以2為級數的原因是解碼器在減采樣時也是選擇以2為級數時最接近的那個數字做減采樣的,具體的闡述可以查看: inSampleSize 的文檔

為了用這個方法,首先在解碼時,將 inJustDecodeBounds 設置為 true ,將選項傳遞進去然后再使用新的 inSampleSize 值解碼,并把 inJustDecodeBounds 設置為 false

      
        public
      
      
        static
      
       Bitmap decodeSampledBitmapFromResource(Resources res, 
      
        int
      
      
         resId,

        
      
      
        int
      
       reqWidth, 
      
        int
      
      
         reqHeight) {



    
      
      
        //
      
      
         First decode with inJustDecodeBounds=true to check dimensions
      
      
        final
      
       BitmapFactory.Options options = 
      
        new
      
      
         BitmapFactory.Options();

    options.inJustDecodeBounds 
      
      = 
      
        true
      
      
        ;

    BitmapFactory.decodeResource(res, resId, options);



    
      
      
        //
      
      
         Calculate inSampleSize
      
      

    options.inSampleSize =
      
         calculateInSampleSize(options, reqWidth, reqHeight);



    
      
      
        //
      
      
         Decode bitmap with inSampleSize set
      
      

    options.inJustDecodeBounds = 
      
        false
      
      
        ;

    
      
      
        return
      
      
         BitmapFactory.decodeResource(res, resId, options);

}
      
    

這個方法使得將任意大尺寸的圖片加載到值顯示100x100大小的 ImageView 中時,非常方便,就像下面代碼所顯示的那樣:

      
        mImageView.setImageBitmap(

    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 
      
      100, 100));
    

你也可以通過替換適當的 BitmapFactory.decode* 方法(如果需要的話),對來自其他源的照片做類似的處理過程。

【Android Developers Training】 56. 更效率地加載大圖片


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精品视频一区二区三区在线播放 | 日本亚欧乱色视频在线网站 | 色网址在线观看 | 日日日操操操 | 擼擼色在线看观看免费 | 日一区二区| 99视频精品免视3 | 99热久久国产这里有只有精品 | 香蕉网站狼人久久五月亭亭 | 亚洲日本视频 | 国内精品免费一区二区三区 | 久久91这里精品国产2020 | 亚洲精品久久婷婷爱久久婷婷 | 成人精品视频一区二区在线 | 老司机福利深夜亚洲入口 | 国产在线精品一区免费香蕉 | 中文字幕日韩哦哦哦 | 国产91精品系列在线观看 | 伊人久久网国产伊人 | 中文字幕或区 | 狠狠久久久久综合网 | 日韩视频免费一区二区三区 | ass曰本人乱妇ass | 国产理论视频在线观看 | 久久这里只精品热在线8 | 亚洲国产成人精品激情 | 欧美日韩一区二区三区毛片 | 人人看97| 尹人香蕉久久99天天 | 久热中文字幕在线精品免费 | 精品哟哟国产在线观看 | 热久久这里是精品6免费观看 | 久久精品亚洲一级毛片 | 香蕉视频一区二区 | 手机福利片 | 国产福利视频在线观看 | 日本激情视频一区二区三区 | 成人在线黄色 | 国产麻豆va精品视频 | 亚洲午夜久久影院 | 91久久精品|