android图片压缩办法总结

来源:互联网 发布:链家端口报买系统图片 编辑:程序博客网 时间:2024/06/05 12:00

在Android中 如果 有图片 就 狠狠地压缩处理,如果 不处理,到最后处理起来 很麻烦的,引起不必要的麻烦,和浪费时间……

这里 提供一个工具类:


package com.jiayinlending.function.mine;/** * Created by ${wenjing} on 2017/5/26. */import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.util.Base64;import android.util.Log;/** * Image compress factory class * * @author * */public class ImageFactory {    /**     * Get bitmap from specified image path     *     * @param imgPath     * @return     */    public 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);    }    /**     * Store bitmap into specified image path     *     * @param bitmap     * @param outPath     * @throws FileNotFoundException     */    public void storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException {        FileOutputStream os = new FileOutputStream(outPath);        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);    }    /**     * Compress image by pixel, this will modify image width/height.     * Used to get thumbnail     *     * @param imgPath image path     * @param pixelW target pixel of width     * @param pixelH target pixel of height     * @return     */    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 compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除        return bitmap;    }    /**     * Compress image by size, this will modify image width/height.     * Used to get thumbnail     *     * @param image     * @param pixelW target pixel of width     * @param pixelH target pixel of height     * @return     */    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 compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除        return bitmap;    }    /**     * Compress by quality,  and generate image to the path specified     *     * @param image     * @param outPath     * @param maxSize target will be compressed to be smaller than this size.(kb)     * @throws IOException     */    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();    }    /**     * Compress by quality,  and generate image to the path specified     *     * @param imgPath     * @param outPath     * @param maxSize target will be compressed to be smaller than this size.(kb)     * @param needsDelete Whether delete original file after compress     * @throws IOException     */    public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {        compressAndGenImage(getBitmap(imgPath), outPath, maxSize);        // Delete original file        if (needsDelete) {            File file = new File (imgPath);            if (file.exists()) {                file.delete();            }        }    }    /**     * Ratio and generate thumb to the path specified     *     * @param image     * @param outPath     * @param pixelW target pixel of width     * @param pixelH target pixel of height     * @throws FileNotFoundException     */    public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException {        Bitmap bitmap = ratio(image, pixelW, pixelH);        storeImage( bitmap, outPath);    }    /**     * Ratio and generate thumb to the path specified     *     * @param outPath     * @param pixelW target pixel of width     * @param pixelH target pixel of height     * @param needsDelete Whether delete original file after compress     * @throws FileNotFoundException     */    public void ratioAndGenThumb(String imgPath, String outPath, float pixelW, float pixelH, boolean needsDelete) throws FileNotFoundException {        Bitmap bitmap = ratio(imgPath, pixelW, pixelH);        storeImage( bitmap, outPath);        // Delete original file        if (needsDelete) {            File file = new File (imgPath);            if (file.exists()) {                file.delete();            }        }    }//    如果上面的工具类不满足你,那么看看下面的方法。//    一、图片质量压缩    /**     * 质量压缩方法     *     * @param image     * @return     */    public static Bitmap compressImage(Bitmap image) {        ByteArrayOutputStream baos = new ByteArrayOutputStream();        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中        int options = 90;        while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩            baos.reset(); // 重置baos即清空baos            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中            options -= 10;// 每次都减少10        }        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片        return bitmap;    }//    二、按比例大小压缩 (路径获取图片)    /**     * 图片按比例大小压缩方法     *     * @param srcPath (根据路径获取图片并压缩)     * @return     */    public static Bitmap getimage(String srcPath) {        BitmapFactory.Options newOpts = new BitmapFactory.Options();        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了        newOpts.inJustDecodeBounds = true;        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空        newOpts.inJustDecodeBounds = false;        int w = newOpts.outWidth;        int h = newOpts.outHeight;        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为        float hh = 800f;// 这里设置高度为800f        float ww = 480f;// 这里设置宽度为480f        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可        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(srcPath, newOpts);        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩    }//    三、按比例大小压缩 (Bitmap)    /**     * 图片按比例大小压缩方法     *     * @param image (根据Bitmap图片压缩)     * @return     */    public static Bitmap compressScale(Bitmap image) {        ByteArrayOutputStream baos = new ByteArrayOutputStream();        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);        // 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出        if (baos.toByteArray().length / 1024 > 1024) {            baos.reset();// 重置baos即清空baos            image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 这里压缩50%,把压缩后的数据存放到baos中        }        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());        BitmapFactory.Options newOpts = new BitmapFactory.Options();        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了        newOpts.inJustDecodeBounds = true;        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);        newOpts.inJustDecodeBounds = false;        int w = newOpts.outWidth;        int h = newOpts.outHeight;        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为        // float hh = 800f;// 这里设置高度为800f        // float ww = 480f;// 这里设置宽度为480f        float hh = 512f;        float ww = 512f;        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可        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; // 设置缩放比例        // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了        isBm = new ByteArrayInputStream(baos.toByteArray());        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩        //return bitmap;    }//    分享个按照图片尺寸压缩:    public static void compressPicture(String srcPath, String desPath) {        FileOutputStream fos = null;        BitmapFactory.Options op = new BitmapFactory.Options();        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了        op.inJustDecodeBounds = true;        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, op);        op.inJustDecodeBounds = false;        // 缩放图片的尺寸        float w = op.outWidth;        float h = op.outHeight;        float hh = 1024f;//        float ww = 1024f;//        // 最长宽度或高度1024        float be = 1.0f;        if (w > h && w > ww) {            be = (float) (w / ww);        } else if (w < h && h > hh) {            be = (float) (h / hh);        }        if (be <= 0) {            be = 1.0f;        }        op.inSampleSize = (int) be;// 设置缩放比例,这个数字越大,图片大小越小.        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了        bitmap = BitmapFactory.decodeFile(srcPath, op);        int desWidth = (int) (w / be);        int desHeight = (int) (h / be);        bitmap = Bitmap.createScaledBitmap(bitmap, desWidth, desHeight, true);        try {            fos = new FileOutputStream(desPath);            if (bitmap != null) {                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);            }        } catch (FileNotFoundException e) {            e.printStackTrace();        }    } /*   需要注意两个问题:    一、调用getDrawingCache()前先要测量,否则的话得到的bitmap为null,这个我在OnCreate()、OnStart()、OnResume()方法里都试验过。    二、当调用bitmap.compress(CompressFormat.JPEG, 100, fos);保存为图片时发现图片背景为黑色,如下图:    这时只需要改成用png保存就可以了,bitmap.compress(CompressFormat.PNG, 100, fos);,如下图:    在实际开发中,有时候我们需求将文件转换为字符串,然后作为参数进行上传。    必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式*/        import android.graphics.Bitmap;    import android.graphics.BitmapFactory;    import android.util.Base64;    import java.io.ByteArrayOutputStream;    /**     *     *     * 功能描述:Android开发之常用必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式     */    public class BitmapAndStringUtils {        /**         * 图片转成string         *         * @param bitmap         * @return         */        public static String convertIconToString(Bitmap bitmap)        {            ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);            byte[] appicon = baos.toByteArray();// 转为byte数组            return Base64.encodeToString(appicon, Base64.DEFAULT);        }        /**         * string转成bitmap         *         * @param st         */        public static Bitmap convertStringToIcon(String st)        {            // OutputStream out;            Bitmap bitmap = null;            try            {                // out = new FileOutputStream("/sdcard/aa.jpg");                byte[] bitmapArray;                bitmapArray = Base64.decode(st, Base64.DEFAULT);                bitmap =                        BitmapFactory.decodeByteArray(bitmapArray, 0,                                bitmapArray.length);                // bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);                return bitmap;            }            catch (Exception e)            {                return null;            }        }    }//    如果你的图片是File文件,可以用下面代码:    /**     * 图片文件转换为指定编码的字符串     *     * @param imgFile  图片文件     */    public static String file2String(File imgFile) {        InputStream in = null;        byte[] data = null;        //读取图片字节数组        try{            in = new FileInputStream(imgFile);            data = new byte[in.available()];            in.read(data);            in.close();        } catch (IOException e){            e.printStackTrace();        }        //对字节数组Base64编码        BASE64Encoder encoder = new BASE64Encoder();        String result = encoder.encode(data);        return result;//返回Base64编码过的字节数组字符串    }}

原创粉丝点击