`

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 开发中,加载大图片时经常会出现内存溢出的问题。这是由于大图片的解码需要大量的内存空间,从而导致应用程序崩溃。因此,解决加载大图片时的内存溢出问题是...

    android解决加载图片内存溢出

    在Android开发中,图片加载是常见且关键的操作,但如果不恰当处理,很容易导致内存溢出(Out of Memory,简称OOM)问题。内存溢出不仅会影响应用的性能,降低用户体验,严重时甚至会导致应用崩溃。本篇文章将深入...

    android 轻松避免内存溢出

    综上所述,处理Android中的图片内存溢出问题需要综合运用多种策略,结合特定场景进行优化。本项目提供的工具类是对此问题的一种解决方案,对于Android开发者来说,理解和应用这些方法,可以显著提升应用的性能和稳定...

    Android 内存溢出问题

    本篇文章将深入探讨Android内存管理的两个核心概念:堆(Heap)和栈(Stack),以及如何理解和解决Android内存溢出问题。 1. 堆与栈 堆和栈是Java虚拟机(JVM)中的两种主要内存区域,它们各自具有特定的用途和...

    android 图片下载 有效解决内存溢出问题

    在Android开发中,图片下载和显示是常见的操作,但如果不恰当处理,很容易引发内存溢出(Out of Memory,简称OOM)问题。内存溢出是指程序在申请内存时,没有足够的内存空间供其使用,导致程序崩溃。对于Android应用...

    android双缓冲解决图片内存溢出的问题

    在Android开发中,处理大量的图片资源时,常常会遇到内存溢出(Out Of Memory,简称OOM)的问题。这是因为Android系统为每个应用分配的内存有限,当加载过多或过大的图片时,很容易超出这个限制,导致应用崩溃。为了...

    android_内存溢出处理

    解决加载图片内存溢出的问题 在加载图片时,需要注意图片的大小不能超过 RAM 的内存。如果图片的大小超过了 RAM 的内存,就会出现 java.lang.OutOfMemoryError:bitmap size exceeds VM budget 异常。解决这个问题...

    android 处理图片内存溢出 VM.pdf

    总之,处理Android中的图片内存溢出问题,关键在于合理地缩放图片,使用BitmapFactory.Options的`inSampleSize`和`inJustDecodeBounds`属性,以及通过`computeSampleSize()`计算合适的缩放比例。这样可以有效地减少...

    android图片浏览器,没有内存溢出

    在Android平台上开发一款图片浏览器,一个常见的挑战是处理大量图片时可能出现的内存溢出问题。内存溢出(Memory Leak)是指程序在申请内存后,无法释放已申请的内存空间,一次次积累后,系统可用内存越来越少,最终...

    android缩放图片代码实例

    本文将深入探讨如何在Android中有效地缩放图片,以避免内存溢出(Out Of Memory,简称OOM)问题,提升应用的运行效率。 ### 1. 图片缩放原理 Android中的图片缩放主要涉及到两个关键概念:`Bitmap`对象和` ...

    gallery加载大量图片时内存溢出的解决方法(一)

    在开发Android应用时,尤其是创建图像画廊或者类似功能时,加载大量图片常常会导致内存溢出(Out Of Memory,简称OOM)。这是因为Android系统为每个应用程序分配的内存是有限的,而图片是占用内存的主要因素之一。...

    ListView优化及加载图片时内存溢出

    - **使用高效的图片库**:如Glide、Picasso等,它们都内置了内存和磁盘缓存机制,能够根据屏幕尺寸智能地加载和缩放图片,减少内存消耗。 - **Bitmap配置**:合理设置Bitmap的配置,如压缩格式、颜色模式、样本...

    Android加载图片内存溢出问题解决方法

    在Android应用开发中,图片加载是常见的操作,但如果不恰当处理,可能会导致内存溢出(Out Of Memory,简称OOM)问题。尤其当处理大尺寸图片时,由于Bitmap对象会占用大量内存,很容易超出Android设备的内存限制。...

    Android图片裁剪----移动、缩放图片进行裁剪

    为了避免内存溢出,可以考虑使用Bitmap的inSampleSize来降低图片加载的分辨率,或者使用BitmapRegionDecoder来按需解码部分图像。 JImageEditDemo可能是一个示例项目,包含了以上所述的实现。这个项目可能包括了...

    android 缩放图片上添加文字

    - 对于大图,为了避免内存溢出,可以使用`inSampleSize`参数来降低Bitmap的解码分辨率。 - 使用`Bitmap.createBitmap()`时,根据实际需要创建合适大小的Bitmap,避免浪费内存。 - 使用`Canvas`的`save()`和`...

    android 解决ViewPager加载大量图片内存溢出问题

    然而,当ViewPager中加载大量图片时,如果不进行优化,很容易导致内存溢出(Out of Memory,OOM)的问题。这是因为Android系统为每个可见页面都加载了图片资源,随着用户滑动,内存中会积累过多的图片对象,从而消耗...

    android图片预览缩放

    可以使用Bitmap的`inSampleSize`参数来降低图片的加载分辨率,或者利用Android的Nine-Patch技术减少图片内存占用。同时,合理使用软引用(`SoftReference`)或弱引用(`WeakReference`)存储Bitmap,以便在内存紧张...

    Android应用源码之防止内存溢出浅析-IT计算机-毕业设计.zip

    在Android应用开发中,内存管理是至关重要的一个环节,尤其是防止内存溢出(Out Of Memory,简称OOM)。本文将深入浅出地分析Android应用源码中如何预防内存溢出问题,帮助开发者提升应用性能和稳定性。 一、...

    图片再大都不会内存溢出

    5. **第三方库的使用**:像 Glide、Picasso 和 Fresco 这样的库,专门处理图片加载,它们优化了内存管理,自动处理图片的解码和缩放,可以防止内存溢出。例如,Glide通过延迟加载和占位符机制,确保在图片未完全加载...

    android图片缩放放大

    当处理大图时,为避免内存溢出,通常需要进行加载优化。使用`BitmapFactory.Options`可以控制解码时的配置,如设置`inSampleSize`来降低图片的分辨率,从而减少内存占用。 5. **动画效果**: 在Android中,可以...

Global site tag (gtag.js) - Google Analytics