Android处理大图片

Android处理大图的方法:

对于大图先获取出图片的width和height, 然后根据view的width和height, 换算出图片inSampleSize,,最后压缩生成相应的图片。

其中重要的两个参数是:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**  
  2. 111         * If set to true, the decoder will return null (no bitmap), but  
  3. 112         * the out... fields will still be set, allowing the caller to query  
  4. 113         * the bitmap without having to allocate the memory for its pixels.  
  5. 114         */  
  6. 115        public boolean inJustDecodeBounds;  
  7. 116  
  8. 117        /**  
  9. 118         * If set to a value > 1, requests the decoder to subsample the original  
  10. 119         * image, returning a smaller image to save memory. The sample size is  
  11. 120         * the number of pixels in either dimension that correspond to a single  
  12. 121         * pixel in the decoded bitmap. For example, inSampleSize == 4 returns  
  13. 122         * an image that is 1/4 the width/height of the original, and 1/16 the  
  14. 123         * number of pixels. Any value <= 1 is treated the same as 1. Note: the  
  15. 124         * decoder uses a final value based on powers of 2, any other value will  
  16. 125         * be rounded down to the nearest power of 2.  
  17. 126         */  
  18. 127        public int inSampleSize;  

InJustDecodeBounds能在不分配资源给图片的情况下获取图片的大小


inSampleSize计算图片的压缩比


开源项目xutils, Universal-Image-Loader和Foursquare对于大图的处理都类似的


下面是Foursquare处理大图的代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class ImageUtils {  
  2.       
  3.     private ImageUtils() {  
  4.     }  
  5.   
  6.     public static void resampleImageAndSaveToNewLocation(String pathInput, String pathOutput)   
  7.         throws Exception   
  8.     {  
  9.         Bitmap bmp = resampleImage(pathInput, 640);  
  10.           
  11.         OutputStream out = new FileOutputStream(pathOutput);  
  12.         bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);   
  13.     }  
  14.       
  15.     public static Bitmap resampleImage(String path, int maxDim)   
  16.         throws Exception {  
  17.           
  18.         BitmapFactory.Options bfo = new BitmapFactory.Options();   
  19.         bfo.inJustDecodeBounds = true;   
  20.         BitmapFactory.decodeFile(path, bfo);   
  21.       
  22.         BitmapFactory.Options optsDownSample = new BitmapFactory.Options();  
  23.         optsDownSample.inSampleSize = getClosestResampleSize(bfo.outWidth, bfo.outHeight, maxDim);  
  24.       
  25.         Bitmap bmpt = BitmapFactory.decodeFile(path, optsDownSample);  
  26.       
  27.         Matrix m = new Matrix();   
  28.           
  29.         if (bmpt.getWidth() > maxDim || bmpt.getHeight() > maxDim) {  
  30.             BitmapFactory.Options optsScale = getResampling(bmpt.getWidth(), bmpt.getHeight(), maxDim);  
  31.             m.postScale((float)optsScale.outWidth  / (float)bmpt.getWidth(),   
  32.                         (float)optsScale.outHeight / (float)bmpt.getHeight());   
  33.         }  
  34.            
  35.         int sdk = new Integer(Build.VERSION.SDK).intValue();   
  36.         if (sdk > 4) {  
  37.             int rotation = ExifUtils.getExifRotation(path);  
  38.             if (rotation != 0) {   
  39.                 m.postRotate(rotation);   
  40.             }  
  41.         }  
  42.           
  43.         return Bitmap.createBitmap(bmpt, 00, bmpt.getWidth(), bmpt.getHeight(), m, true);   
  44.     }  
  45.       
  46.     private static BitmapFactory.Options getResampling(int cx, int cy, int max) {  
  47.         float scaleVal = 1.0f;  
  48.         BitmapFactory.Options bfo = new BitmapFactory.Options();  
  49.         if (cx > cy) {  
  50.             scaleVal = (float)max / (float)cx;  
  51.         }  
  52.         else if (cy > cx) {  
  53.             scaleVal = (float)max / (float)cy;  
  54.         }  
  55.         else {  
  56.             scaleVal = (float)max / (float)cx;  
  57.         }  
  58.         bfo.outWidth  = (int)(cx * scaleVal + 0.5f);  
  59.         bfo.outHeight = (int)(cy * scaleVal + 0.5f);  
  60.         return bfo;  
  61.     }  
  62.       
  63.     private static int getClosestResampleSize(int cx, int cy, int maxDim) {  
  64.         int max = Math.max(cx, cy);  
  65.           
  66.         int resample = 1;  
  67.         for (resample = 1; resample < Integer.MAX_VALUE; resample++) {  
  68.             if (resample * maxDim > max) {  
  69.                 resample--;  
  70.                 break;  
  71.             }  
  72.         }  
  73.           
  74.         if (resample > 0) {  
  75.             return resample;  
  76.         }  
  77.         return 1;  
  78.     }  
  79.       
  80.     public static BitmapFactory.Options getBitmapDims(String path) throws Exception {  
  81.         BitmapFactory.Options bfo = new BitmapFactory.Options();   
  82.         bfo.inJustDecodeBounds = true;   
  83.         BitmapFactory.decodeFile(path, bfo);   
  84.         return bfo;  
  85.     }  
  86. }  

还有一个问题需要纠正:
看了几篇关于处理大图的文章都说不要调用BitmapFactory.decodeResource这个函数,因为这个函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。
我看了BitmapFactory的源码发现上面那个分析是错误的,decodeResource最终也是调用Jni去获取图片。请看下面时序图。


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <pre code_snippet_id="290408" snippet_file_name="blog_20140413_1_8666293"></pre>  
  2. <pre></pre>  
  3. <pre></pre> 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值