`

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();  
    }  
 

 

 

 

 

 

分享到:
评论

相关推荐

    android缩放图片代码实例

    如何为你的Android应用缩放图片,详细比较了android图片显示缩放前后用时,占用内存资源大小。防止加载大图是发生内存溢出

    SubsamplingScaleImageView查看巨图DEMO 解决超大图片OOM 内存溢出 可双击手势缩放 viewpager 局部加载

    * 使用SubsamplingScaleImageView实现局部加载超大图片 巨大图片等. * 自带图片手势缩放和双击放大缩小等功能 * 有效解决 viewpager+fragment 内存溢出OOM

    Android ListView,Gridview动态加载释放图片资源

    但是如果图片多了就会遇到内存溢出的情况,及时你对图片做了缩放处理但是图片张数多了还是一样的会内存溢出。所以这个时候就需要我们动态的释放和加载图片资源。附件中是小弟根据自己的想法实现的动态加载和释放图片...

    android加载大图片

    android加载大图片oom是常遇到的问题,此资源加载前将图片进行缩放,按缩放比例加载缩放后的图片来解决oom问题。Gallery和ImageSwitcher配合展示图片

    仿系统相册,gridview+imagepager+imageloader+图片手势缩放双击放大

    图片的下载缓存用的是imageloader框架,可加载大量图片,不会出现内存溢出。

    Android 实现加载大图片的方法

    对于超大的图片,如果不缩放的话,容易导致内存溢出。而经过处理后,无论多大的图片,都能够在手机屏幕上加载出来,不会导致内存溢出。当然,脸黑的除外 该应用涉及到的知识有: – 1.Bitmap的使用 – 2.Android...

    Android原生图片处理类库

    缩放,旋转,裁剪等,AndroidJniBitmapOperations也是Android原生图片处理类库,通过JNI在bitmaps上执行各种简单的操作,同时还提供在Android使用本地java环境防止出现OOM(内存溢出)的策略。 下面是一些操作: 1、...

    android源码包集合4

    zz-doctor中医大夫助理...防止内存溢出浅析.rar 飞行历 飞行模式 AirPlus.rar 飞行射击类游戏源码.rar 高仿 WIN8系统 磁贴点击下沉倾斜效果源码.zip 高仿基于android2.2(Froyo)的Contacts.zip 高仿多米音乐播放器.rar

    android Bitmap用法总结

    //将图片设为原来宽高的1/2,防止内存溢出 Bitmap bm = BitmapFactory.decodeFile("",option);//文件流 URL url = new URL(""); InputStream is = url.openStream(); Bitmap bm = BitmapFactory.decodeStream(is); ...

    Android典型技术模块开发详解

    目录 第一篇 Android开发初步 ...16.5 Bitmap内存溢出 16.5.1 图片预先缩放 16.5.2 普通的图片缩放方法 16.5.3 Dalvik虚拟机的堆内存分配 16.5.4 Bitmap对象及时释放 16.6 多分辨率适应 16.7 本章小结

    黑马程序员 安卓学院 万元哥项目经理 分享220个代码实例

    |--图片的缩放处理(防内存溢出) |--多媒体应用设计图 |--多线程下载 |--多线程下载及断点续传 |--多线程之AsyncTask的用法 |--多线程之线程池ExecutorService |--字体为粗体 |--安卓下的多线程断点上传 |--对话框与...

    Android中加载网络资源时的优化可使用(线程+缓存)解决

    下面提出一些优化: 1、采用线程池 2、内存缓存+文件缓存 3、内存缓存中网上很多是采用SoftReference来防止堆溢出,这儿严格限制只能使用最大JVM内存的1/4 4、对下载的图片进行按比例缩放,以减少内存的消耗 具体的...

    Android 矢量室内地图开发实例

    3、会导致客户端内存溢出 。。。 因为这些问题,我不得不放弃这种方法。要解决上面的问题只能使用矢量图进行开发了,于是我使用了HTML5进行了矢量图的开发,不仅解决了地图缩放失真等问题,还同时适用于Android、...

Global site tag (gtag.js) - Google Analytics