zoukankan      html  css  js  c++  java
  • 【Android

            很多时候,如果APP需要下载和加载很多图片(尤其是大图片)的时候,就往往会报如下图所示的错误:

            如上图所示,OOM(OutOfMemoryError)表示内存溢出,这是因为网络或内存中的图片被加载成Bitmap时耗费的内存超出了系统内存而造成内存溢出。解决这个问题有很多方法,这里主要介绍其中的一种方法:图片压缩。

            这里贴出一个工具类:

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.BitmapFactory;
    
    /**
     * 图片压缩工具类
     */
    public class ImageUtil {
        /**
         * 从指定路径获取Bitmap图片
         *
         * @param imgPath 原始图片的路径
         */
        public static Bitmap getBitmap(String imgPath) {
            // Get bitmap through image path  
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inJustDecodeBounds = false;
            newOpts.inPurgeable = true;
            newOpts.inInputShareable = true;
            // Do not compress  
            newOpts.inSampleSize = 1;
            newOpts.inPreferredConfig = Config.RGB_565;
            return BitmapFactory.decodeFile(imgPath, newOpts);
        }
    
        /**
         * 将图片存储到指定路径的文件中
         *
         * @param bitmap  原始图片Bitmap
         * @param outPath 目标图片路径
         */
        public static void storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException {
            FileOutputStream os = new FileOutputStream(outPath);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
        }
    
        /**
         * 尺寸压缩(改变图片的宽高),适合用于加载缩略图
         *
         * @param imgPath 图片路径
         * @param pixelW  想要将图片压缩到的宽度
         * @param pixelH  想要将图片压缩到的高度
         */
        public Bitmap ratio(String imgPath, float pixelW, float pixelH) {
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            // 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容  
            newOpts.inJustDecodeBounds = true;
            newOpts.inPreferredConfig = Config.RGB_565;
            // Get bitmap info, but notice that bitmap is null now    
            Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
    
            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            // 想要缩放的目标尺寸  
            float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了  
            float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了  
            // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可    
            int be = 1;//be=1表示不缩放    
            if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放    
                be = (int) (newOpts.outWidth / ww);
            } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放    
                be = (int) (newOpts.outHeight / hh);
            }
            if (be <= 0) be = 1;
            newOpts.inSampleSize = be;//设置缩放比例  
            // 开始压缩图片,注意此时已经把options.inJustDecodeBounds 设回false了  
            bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
            return bitmap;
        }
    
        /**
         * 尺寸压缩(改变图片的宽高),适合用于加载缩略图
         *
         * @param image  图片的Bitmap
         * @param pixelW 想要将图片压缩到的宽度
         * @param pixelH 想要将图片压缩到的高度
         */
        public Bitmap ratio(Bitmap image, float pixelW, float pixelH) {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.JPEG, 100, os);
            if (os.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
                os.reset();//重置baos即清空baos    
                image.compress(Bitmap.CompressFormat.JPEG, 50, os);//这里压缩50%,把压缩后的数据存放到baos中    
            }
            ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            //开始读入图片,此时把options.inJustDecodeBounds 设回true了    
            newOpts.inJustDecodeBounds = true;
            newOpts.inPreferredConfig = Config.RGB_565;
            Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts);
            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了  
            float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了  
            //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可    
            int be = 1;//be=1表示不缩放    
            if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放    
                be = (int) (newOpts.outWidth / ww);
            } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放    
                be = (int) (newOpts.outHeight / hh);
            }
            if (be <= 0) be = 1;
            newOpts.inSampleSize = be;//设置缩放比例    
            //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了    
            is = new ByteArrayInputStream(os.toByteArray());
            bitmap = BitmapFactory.decodeStream(is, null, newOpts);
            return bitmap;
        }
    
        /**
         * 质量压缩,然后存储到指定路径
         *
         * @param image   原始图片Bitmap
         * @param outPath 目标图片路径
         * @param maxSize 图片将被压缩成这么多KB
         */
        public void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            // scale  
            int options = 100;
            // Store the bitmap into output stream(no compress)  
            image.compress(Bitmap.CompressFormat.JPEG, options, os);
            // Compress by loop  
            while (os.toByteArray().length / 1024 > maxSize) {
                // Clean up os  
                os.reset();
                // interval 10  
                options -= 10;
                image.compress(Bitmap.CompressFormat.JPEG, options, os);
            }
            // Generate compressed image file  
            FileOutputStream fos = new FileOutputStream(outPath);
            fos.write(os.toByteArray());
            fos.flush();
            fos.close();
        }
    
        /**
         * 质量压缩并存储到指定路径
         *
         * @param imgPath     想要压缩的图片路径
         * @param outPath     目标图片路径
         * @param maxSize     图片将被压缩成这么多KB
         * @param needsDelete 压缩后是否删除原始图片
         */
        public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {
            compressAndGenImage(getBitmap(imgPath), outPath, maxSize);
            if (needsDelete) {
                File file = new File(imgPath);
                if (file.exists()) {
                    file.delete();
                }
            }
        }
    
        /**
         * 尺寸压缩后保存图片
         *
         * @param image   原始图片Bitmap
         * @param outPath 目标图片路径
         * @param pixelW  想要将图片压缩到的宽度
         * @param pixelH  想要将图片压缩到的高度
         */
        public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException {
            Bitmap bitmap = ratio(image, pixelW, pixelH);
            storeImage(bitmap, outPath);
        }
    
        /**
         * 尺寸压缩后保存图片,并决定是否删除原始图片
         *
         * @param imgPath     想要压缩的图片路径
         * @param outPath     目标图片路径
         * @param pixelW      想要将图片压缩到的宽度
         * @param pixelH      想要将图片压缩到的高度
         * @param needsDelete 是否删除原始图片
         */
        public void ratioAndGenThumb(String imgPath, String outPath, float pixelW, float pixelH, boolean needsDelete) throws FileNotFoundException {
            Bitmap bitmap = ratio(imgPath, pixelW, pixelH);
            storeImage(bitmap, outPath);
            if (needsDelete) {
                File file = new File(imgPath);
                if (file.exists()) {
                    file.delete();
                }
            }
        }
    }
  • 相关阅读:
    VS工具箱不显示DEV控件解决方法
    Win服务程序编写以及安装一般步骤
    cmd命令行带参启动程序
    C#递归拷贝文件夹下文件以及文件夹
    WPF中ComboBox控件绑定键值对操作
    MySQL学习(二)
    Mysql学习(一)
    XML学习(二)
    XML学习(一)
    关于Oracle本地连接出现与监听有关的问题的解决方法探讨
  • 原文地址:https://www.cnblogs.com/itgungnir/p/6211027.html
Copyright © 2011-2022 走看看