android 缩放图片与内存溢出

常用的Android版缩放图片代码:  ContentResolver cr = this.getContentResolver();  

    try  
    {  
        InputStream in = cr.openInputStream(uri);  
        Bitmap bitmap = BitmapFactory.decodeStream(in);  
        try  
        {  
            in.close();  
        }  
        catch (IOException e)  
        {  
            e.printStackTrace();  
        }  
        if(null  == bitmap)  
        {  
            Toast.makeText(this, "Head is not set successful,Decode bitmap failure", 2000);  
        }  
        //原始图片的尺寸  
        int bmpWidth  = bitmap.getWidth();  
        int bmpHeight = bitmap.getHeight();  
          
        //缩放图片的尺寸  
        float scaleWidth  = (float) 40 / bmpWidth;  
        float scaleHeight = (float) 40 / bmpHeight;  
        Matrix matrix = new Matrix();  
        matrix.postScale(scaleWidth, scaleHeight);  
          
        //产生缩放后的Bitmap对象  
        Bitmap resizeBitmap = Bitmap.createBitmap(  
            bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false);  
        bitmap.recycle();  
        //Bitmap to byte[]  
        byte[] photoData = Bitmap2Bytes(resizeBitmap);  
          
        //save file  
        String fileName = "/sdcard/test.jpg";  
        FileUtil.writeToFile(fileName, photoData);  
          
        //save photo check sum to db  
        DataCenter.GetInstance().ModifyIMMUser();  
        //refresh ImageView  
    }  
    catch (FileNotFoundException exp)  
    {  
        exp.printStackTrace();  
    }  

  如果图片非常大,在执行BitmapFactory.decodeStream的时候就会抛出OOM异常。 

我们来看看系统应用MMS是如何处理的,SMS添加了多媒体附件后就作MMS处理了,当附加文件原图超过300K,也会做个缩放处理,具体参考:com.android.mms.ui/.UriImage: 

 

 

 

 package com.android.mms.ui;  
    public class UriImage  
    {  
        private int mWidth;  
        private int mHeight;  
        ... ...  
        //  
        private void decodeBoundsInfo()  
        {  
            InputStream input = null;  
            try  
            {  
                input = mContext.getContentResolver().openInputStream(mUri);  
                BitmapFactory.Options opt = new BitmapFactory.Options();  
                opt.inJustDecodeBounds = true;//只描边,不读取数据  
                BitmapFactory.decodeStream(input, null, opt);  
                mWidth = opt.outWidth;  
                mHeight = opt.outHeight;  
            }  
            catch (FileNotFoundException e)  
            {  
                // Ignore  
                Log.e(TAG, "IOException caught while opening stream", e);  
            }  
            finally  
            {  
                if (null != input) {  
                    try {  
                        input.close();  
                    } catch (IOException e) {  
                        // Ignore  
                        Log.e(TAG, "IOException caught while closing stream", e);  
                    }  
                }  
            }  
        }  
        private byte[] getResizedImageData(int widthLimit, int heightLimit)  
        {  
            int outWidth = mWidth;  
            int outHeight = mHeight;  
            int s = 1;  
            while ((outWidth / s > widthLimit) || (outHeight / s > heightLimit))  
            {  
                s *= 2;  
            }  
            //先设置选项  
            BitmapFactory.Options options = new BitmapFactory.Options();  
            //returning a smaller image to save memory.  
            options.inSampleSize = s;  
            InputStream input = null;  
            try  
            {  
                input = mContext.getContentResolver().openInputStream(mUri);  
                Bitmap b = BitmapFactory.decodeStream(input, null, options);//注意看options的用法  
                if (b == null) {  
                    return null;  
                }  
                ByteArrayOutputStream os = new ByteArrayOutputStream();  
                b.compress(CompressFormat.JPEG, MessageUtils.IMAGE_COMPRESSION_QUALITY, os);  
                return os.toByteArray();  
            } catch (FileNotFoundException e) {  
                Log.e(TAG, e.getMessage(), e);  
                return null;  
            } finally {  
                if (input != null) {  
                    try {  
                        input.close();  
                    } catch (IOException e) {  
                        Log.e(TAG, e.getMessage(), e);  
                    }  
                }  
            }  
        }  
        ... ...  
    }  

  可以看出,MMS应用的方法是:先设置缩放选项,再读取缩放的图片数据到内存,规避了内存引起的OOM。 

修改后的代码: 

 

 

 

   ContentResolver cr = this.getContentResolver();  
        try  
        {  
            InputStream in = cr.openInputStream(uri);  
               BitmapFactory.Options options = new BitmapFactory.Options();  
               options.inJustDecodeBounds = true;  
               BitmapFactory.decodeStream(in, null, options);  
            try  
            {  
        in.close();  
    }  
            catch (IOException e)  
            {  
        e.printStackTrace();  
    }  
               int mWidth = options.outWidth;  
               int mHeight = options.outHeight;  
                 
               int sWidth  = 40;  
               int sHeight = 40;  
                 
            int s = 1;  
            while ((mWidth / s > sWidth * 2) || (mHeight / s > sHeight * 2))  
            {  
                s *= 2;  
            }  
               options = new BitmapFactory.Options();  
            options.inSampleSize = s;  
            in = cr.openInputStream(uri);  
            Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);  
            try  
            {  
        in.close();  
    }  
            catch (IOException e)  
            {  
        e.printStackTrace();  
    }  
            if(null  == bitmap)  
            {  
                Toast.makeText(this, "Head is not set successful,Decode bitmap failure", 2000);  
                return ;  
            }  
            //原始图片的尺寸  
            int bmpWidth  = bitmap.getWidth();  
            int bmpHeight = bitmap.getHeight();  
              
            //缩放图片的尺寸  
            float scaleWidth  = (float) sWidth / bmpWidth;  
            float scaleHeight = (float) sHeight / bmpHeight;  
            Matrix matrix = new Matrix();  
            matrix.postScale(scaleWidth, scaleHeight);  
              
            //产生缩放后的Bitmap对象  
            Bitmap resizeBitmap = Bitmap.createBitmap(  
                bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false);  
            bitmap.recycle();  
                    Bitmap resizeBitmap = bitmap;  
            //Bitmap to byte[]  
            byte[] photoData = bitmap2Bytes(resizeBitmap);  
              
            //save file  
            String fileName = "/sdcard/test.jpg";  
            FileUtil.writeToFile(fileName, photoData);  
 private byte[] bitmap2Bytes(Bitmap bm)  
    {  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
        return baos.toByteArray();  
    }  
 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值