查看: 864|回复: 1

[Android] 【参赛】Android 图片压缩,基于比例和质量压缩

[复制链接]
  • TA的每日心情

    2015-6-25 12:42
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2014-6-29 17:07:02 | 显示全部楼层 |阅读模式
    1. package cc.util.android.image;

    2. import java.io.ByteArrayOutputStream;
    3. import java.io.File;
    4. import java.io.FileOutputStream;
    5. import java.io.IOException;
    6. import java.io.InputStream;
    7. import java.math.BigDecimal;
    8. import java.math.RoundingMode;
    9. import java.nio.ByteBuffer;
    10. import java.nio.channels.Channels;
    11. import java.nio.channels.ReadableByteChannel;
    12. import android.content.Context;
    13. import android.content.res.Resources;
    14. import android.graphics.Bitmap;
    15. import android.graphics.Bitmap.CompressFormat;
    16. import android.graphics.BitmapFactory;
    17. import android.graphics.BitmapFactory.Options;
    18. import android.graphics.Matrix;
    19. import android.media.ExifInterface;
    20. import android.util.Log;

    21. /**
    22. * A class for helping deal the bitmap,
    23. *  like: get the orientation of the bitmap, compress bitmap etc.
    24. * @author wangcccong
    25. * @version 1.140122
    26. * crated at: 2014-03-22
    27. * update at: 2014-06-26
    28. */
    29. public class BitmapHelper {

    30.         /**
    31.          * get the orientation of the bitmap {@link android.media.ExifInterface}
    32.          * @param path
    33.          * @return
    34.          */
    35.         public final static int getDegress(String path) {
    36.                 int degree = 0;
    37.         try {
    38.             ExifInterface exifInterface = new ExifInterface(path);
    39.             int orientation = exifInterface.getAttributeInt(
    40.                     ExifInterface.TAG_ORIENTATION,
    41.                     ExifInterface.ORIENTATION_NORMAL);
    42.             switch (orientation) {
    43.             case ExifInterface.ORIENTATION_ROTATE_90:
    44.                 degree = 90;
    45.                 break;
    46.             case ExifInterface.ORIENTATION_ROTATE_180:
    47.                 degree = 180;
    48.                 break;
    49.             case ExifInterface.ORIENTATION_ROTATE_270:
    50.                 degree = 270;
    51.                 break;
    52.             }
    53.         } catch (IOException e) {
    54.             e.printStackTrace();
    55.         }
    56.         return degree;
    57.         }
    58.        
    59.         /**
    60.          * rotate the bitmap
    61.          * @param bitmap
    62.          * @param degress
    63.          * @return
    64.          */
    65.         public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
    66.         if (bitmap != null) {
    67.             Matrix m = new Matrix();
    68.             m.postRotate(degress);
    69.             bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
    70.             return bitmap;
    71.         }
    72.         return bitmap;
    73.     }
    74.        
    75.         /**
    76.          * caculate the bitmap sampleSize
    77.          * @param path
    78.          * @return
    79.          */
    80.         public final static int caculateInSampleSize(BitmapFactory.Options options, int rqsW, int rqsH) {
    81.                 final int height = options.outHeight;
    82.             final int width = options.outWidth;
    83.             int inSampleSize = 1;
    84.             if (rqsW == 0 || rqsH == 0) return 1;
    85.             if (height > rqsH || width > rqsW) {
    86.                     final int heightRatio = Math.round((float) height/ (float) rqsH);
    87.                     final int widthRatio = Math.round((float) width / (float) rqsW);
    88.                     inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    89.             }
    90.             return inSampleSize;
    91.         }
    92.        
    93.         /**
    94.          * 压缩指定路径的图片,并得到图片对象
    95.          * @param context
    96.          * @param path bitmap source path
    97.          * @return Bitmap {@link android.graphics.Bitmap}
    98.          */
    99.         public final static Bitmap compressBitmap(String path, int rqsW, int rqsH) {
    100.                 final BitmapFactory.Options options = new BitmapFactory.Options();
    101.                 options.inJustDecodeBounds = true;
    102.                 BitmapFactory.decodeFile(path, options);
    103.             options.inSampleSize = caculateInSampleSize(options, rqsW, rqsH);
    104.             options.inJustDecodeBounds = false;
    105.             return BitmapFactory.decodeFile(path, options);
    106.         }
    107.        
    108.         /**
    109.          * 压缩指定路径图片,并将其保存在缓存目录中,通过isDelSrc判定是否删除源文件,并获取到缓存后的图片路径
    110.          * @param context
    111.          * @param srcPath
    112.          * @param rqsW
    113.          * @param rqsH
    114.          * @param isDelSrc
    115.          * @return
    116.          */
    117.         public final static String compressBitmap(Context context, String srcPath, int rqsW, int rqsH, boolean isDelSrc) {
    118.                 Bitmap bitmap = compressBitmap(srcPath, rqsW, rqsH);
    119.                 File srcFile = new File(srcPath);
    120.                 String desPath = getImageCacheDir(context) + srcFile.getName();
    121.                 int degree = getDegress(srcPath);
    122.                 try {
    123.                         if (degree != 0) bitmap = rotateBitmap(bitmap, degree);
    124.                         File file = new File(desPath);
    125.                         FileOutputStream  fos = new FileOutputStream(file);
    126.                         bitmap.compress(Bitmap.CompressFormat.PNG, 70, fos);
    127.                         fos.close();
    128.                         if (isDelSrc) srcFile.deleteOnExit();
    129.                 } catch (Exception e) {
    130.                         // TODO: handle exception
    131.                         Log.e("BitmapHelper-->compressBitmap", e.getMessage()+"");
    132.                 }
    133.                 return desPath;
    134.         }
    135.        
    136.         /**
    137.          * 此方法过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法
    138.          * @param is
    139.          * @param reqsW
    140.          * @param reqsH
    141.          * @param isAdjust
    142.          * @return
    143.          */
    144.         @Deprecated
    145.         public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH, boolean isAdjust) {
    146.                 Bitmap bitmap = BitmapFactory.decodeStream(is);
    147.                 return compressBitmap(bitmap, reqsW, reqsH, isAdjust);
    148.         }
    149.        
    150.         /**
    151.          * 压缩某个输入流中的图片,可以解决网络输入流压缩问题,并得到图片对象
    152.          * @param context
    153.          * @param path bitmap source path
    154.          * @return Bitmap {@link android.graphics.Bitmap}
    155.          */
    156.         public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH) {
    157.                 try {
    158.                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    159.                         ReadableByteChannel channel = Channels.newChannel(is);
    160.                         ByteBuffer buffer = ByteBuffer.allocate(1024);
    161.                         while (channel.read(buffer) != -1) {
    162.                                 buffer.flip();
    163.                                 while (buffer.hasRemaining()) baos.write(buffer.get());
    164.                                 buffer.clear();
    165.                         }
    166.                         byte[] bts = baos.toByteArray();
    167.                         Bitmap bitmap = compressBitmap(bts, reqsW, reqsH);
    168.                         is.close();
    169.                         channel.close();
    170.                         baos.close();
    171.                         return bitmap;
    172.                 } catch (Exception e) {
    173.                         // TODO: handle exception
    174.                         e.printStackTrace();
    175.                         return null;
    176.                 }
    177.         }
    178.        
    179.         /**
    180.          * 压缩指定byte[]图片,并得到压缩后的图像
    181.          * @param bts
    182.          * @param reqsW
    183.          * @param reqsH
    184.          * @return
    185.          */
    186.         public final static Bitmap compressBitmap(byte[] bts, int reqsW, int reqsH) {
    187.                 final Options options = new Options();
    188.                 options.inJustDecodeBounds = true;
    189.                 BitmapFactory.decodeByteArray(bts, 0, bts.length, options);
    190.                 options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH);
    191.                 options.inJustDecodeBounds = false;
    192.                 return BitmapFactory.decodeByteArray(bts, 0, bts.length, options);
    193.         }
    194.        
    195.         /**
    196.          * 此方法已过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法
    197.          * @param bitmap
    198.          * @param reqsW
    199.          * @param reqsH
    200.          * @return
    201.          */
    202.         @Deprecated
    203.         public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH, boolean isAdjust) {
    204.                 if (bitmap == null || reqsW == 0 || reqsH == 0) return bitmap;
    205.                 if (bitmap.getWidth() > reqsW || bitmap.getHeight() > reqsH) {
    206.                         float scaleX = new BigDecimal(reqsW).divide(new BigDecimal(bitmap.getWidth()), 4, RoundingMode.DOWN).floatValue();
    207.                         float scaleY = new BigDecimal(reqsH).divide(new BigDecimal(bitmap.getHeight()), 4, RoundingMode.DOWN).floatValue();
    208.                         if (isAdjust) {
    209.                                 scaleX = scaleX < scaleY ? scaleX : scaleY;
    210.                                 scaleY = scaleX;
    211.                         }
    212.                         Matrix matrix = new Matrix();
    213.                         matrix.postScale(scaleX, scaleY);
    214.                         bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    215.                 }
    216.                 return bitmap;
    217.         }
    218.        
    219.         /**
    220.          * 压缩已存在的图片对象,并返回压缩后的图片
    221.          * @param bitmap
    222.          * @param reqsW
    223.          * @param reqsH
    224.          * @return
    225.          */
    226.         public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH) {
    227.                 try {
    228.                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    229.                         bitmap.compress(CompressFormat.PNG, 100, baos);
    230.                         byte[] bts = baos.toByteArray();
    231.                         Bitmap res = compressBitmap(bts, reqsW, reqsH);
    232.                         baos.close();
    233.                         return res;
    234.                 } catch (IOException e) {
    235.                         // TODO Auto-generated catch block
    236.                         e.printStackTrace();
    237.                         return bitmap;
    238.                 }
    239.         }
    240.        
    241.         /**
    242.          * 此方法过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法
    243.          * get bitmap form resource dictory, and then compress bitmap according to reqsW and reqsH
    244.          * @param res {@link android.content.res.Resources}
    245.          * @param resID
    246.          * @param reqsW
    247.          * @param reqsH
    248.          * @return
    249.          */
    250.         @Deprecated
    251.         public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH, boolean isAdjust) {
    252.                 Bitmap bitmap = BitmapFactory.decodeResource(res, resID);
    253.                 return compressBitmap(bitmap, reqsW, reqsH, isAdjust);
    254.         }
    255.        
    复制代码
  • TA的每日心情

    2015-6-25 12:42
  • 签到天数: 6 天

    [LV.2]偶尔看看I

     楼主| 发表于 2014-6-29 17:08:41 | 显示全部楼层
    接上一段代码

    1.        
    2.         /**
    3.          * 压缩某个输入流中的图片,可以解决网络输入流压缩问题,并得到图片对象
    4.          * @param context
    5.          * @param path bitmap source path
    6.          * @return Bitmap {@link android.graphics.Bitmap}
    7.          */
    8.         public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH) {
    9.                 try {
    10.                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    11.                         ReadableByteChannel channel = Channels.newChannel(is);
    12.                         ByteBuffer buffer = ByteBuffer.allocate(1024);
    13.                         while (channel.read(buffer) != -1) {
    14.                                 buffer.flip();
    15.                                 while (buffer.hasRemaining()) baos.write(buffer.get());
    16.                                 buffer.clear();
    17.                         }
    18.                         byte[] bts = baos.toByteArray();
    19.                         Bitmap bitmap = compressBitmap(bts, reqsW, reqsH);
    20.                         is.close();
    21.                         channel.close();
    22.                         baos.close();
    23.                         return bitmap;
    24.                 } catch (Exception e) {
    25.                         // TODO: handle exception
    26.                         e.printStackTrace();
    27.                         return null;
    28.                 }
    29.         }
    30.        
    31.         /**
    32.          * 压缩指定byte[]图片,并得到压缩后的图像
    33.          * @param bts
    34.          * @param reqsW
    35.          * @param reqsH
    36.          * @return
    37.          */
    38.         public final static Bitmap compressBitmap(byte[] bts, int reqsW, int reqsH) {
    39.                 final Options options = new Options();
    40.                 options.inJustDecodeBounds = true;
    41.                 BitmapFactory.decodeByteArray(bts, 0, bts.length, options);
    42.                 options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH);
    43.                 options.inJustDecodeBounds = false;
    44.                 return BitmapFactory.decodeByteArray(bts, 0, bts.length, options);
    45.         }
    46.        
    47.         /**
    48.          * 此方法已过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法
    49.          * @param bitmap
    50.          * @param reqsW
    51.          * @param reqsH
    52.          * @return
    53.          */
    54.         @Deprecated
    55.         public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH, boolean isAdjust) {
    56.                 if (bitmap == null || reqsW == 0 || reqsH == 0) return bitmap;
    57.                 if (bitmap.getWidth() > reqsW || bitmap.getHeight() > reqsH) {
    58.                         float scaleX = new BigDecimal(reqsW).divide(new BigDecimal(bitmap.getWidth()), 4, RoundingMode.DOWN).floatValue();
    59.                         float scaleY = new BigDecimal(reqsH).divide(new BigDecimal(bitmap.getHeight()), 4, RoundingMode.DOWN).floatValue();
    60.                         if (isAdjust) {
    61.                                 scaleX = scaleX < scaleY ? scaleX : scaleY;
    62.                                 scaleY = scaleX;
    63.                         }
    64.                         Matrix matrix = new Matrix();
    65.                         matrix.postScale(scaleX, scaleY);
    66.                         bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    67.                 }
    68.                 return bitmap;
    69.         }
    70.        
    71.         /**
    72.          * 压缩已存在的图片对象,并返回压缩后的图片
    73.          * @param bitmap
    74.          * @param reqsW
    75.          * @param reqsH
    76.          * @return
    77.          */
    78.         public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH) {
    79.                 try {
    80.                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    81.                         bitmap.compress(CompressFormat.PNG, 100, baos);
    82.                         byte[] bts = baos.toByteArray();
    83.                         Bitmap res = compressBitmap(bts, reqsW, reqsH);
    84.                         baos.close();
    85.                         return res;
    86.                 } catch (IOException e) {
    87.                         // TODO Auto-generated catch block
    88.                         e.printStackTrace();
    89.                         return bitmap;
    90.                 }
    91.         }
    92.        
    93.         /**
    94.          * 此方法过期,该方法可能造成OutOfMemoryError,使用不含isAdjust参数的方法
    95.          * get bitmap form resource dictory, and then compress bitmap according to reqsW and reqsH
    96.          * @param res {@link android.content.res.Resources}
    97.          * @param resID
    98.          * @param reqsW
    99.          * @param reqsH
    100.          * @return
    101.          */
    102.         @Deprecated
    103.         public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH, boolean isAdjust) {
    104.                 Bitmap bitmap = BitmapFactory.decodeResource(res, resID);
    105.                 return compressBitmap(bitmap, reqsW, reqsH, isAdjust);
    106.         }
    107.        
    108.         /**
    109.          * 压缩资源图片,并返回图片对象
    110.          * @param res {@link android.content.res.Resources}
    111.          * @param resID
    112.          * @param reqsW
    113.          * @param reqsH
    114.          * @return
    115.          */
    116.         public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH) {
    117.                 final Options options = new Options();
    118.                 options.inJustDecodeBounds = true;
    119.                 BitmapFactory.decodeResource(res, resID, options);
    120.                 options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH);
    121.                 options.inJustDecodeBounds = false;
    122.                 return BitmapFactory.decodeResource(res, resID, options);
    123.         }
    124.        
    125.        
    126.        
    127.         /**
    128.          * 基于质量的压缩算法, 此方法未 解决压缩后图像失真问题
    129.          * <br> 可先调用比例压缩适当压缩图片后,再调用此方法可解决上述问题
    130.          * @param bts
    131.          * @param maxBytes 压缩后的图像最大大小 单位为byte
    132.          * @return
    133.          */
    134.         public final static Bitmap compressBitmap(Bitmap bitmap, long maxBytes) {
    135.                 try {
    136.                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    137.                         bitmap.compress(CompressFormat.PNG, 100, baos);
    138.                         int options = 90;
    139.                         while (baos.toByteArray().length > maxBytes) {
    140.                                 baos.reset();
    141.                                 bitmap.compress(CompressFormat.PNG, options, baos);
    142.                                 options -= 10;
    143.                         }
    144.                         byte[] bts = baos.toByteArray();
    145.                         Bitmap bmp = BitmapFactory.decodeByteArray(bts, 0, bts.length);
    146.                         baos.close();
    147.                         return bmp;
    148.                 } catch (IOException e) {
    149.                         // TODO Auto-generated catch block
    150.                         e.printStackTrace();
    151.                         return null;
    152.                 }
    153.         }
    154.        
    155. //        public final static Bitmap compressBitmap(InputStream is, long maxBytes) {
    156. //                try {
    157. //                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
    158. //                        byte[] bts = new byte[1024];
    159. //                        while (is.read(bts) != -1) baos.write(bts, 0, bts.length);
    160. //                        is.close();
    161. //                        int options = 100;
    162. //                        while (baos.toByteArray().length > maxBytes) {
    163. //                               
    164. //                        }
    165. //                } catch (Exception e) {
    166. //                        // TODO: handle exception
    167. //                }
    168. //        }
    169.        
    170.         /**
    171.          * 得到指定路径图片的options
    172.          * @param srcPath
    173.          * @return Options {@link android.graphics.BitmapFactory.Options}
    174.          */
    175.         public final static Options getBitmapOptions(String srcPath) {
    176.                 BitmapFactory.Options options = new BitmapFactory.Options();
    177.                 options.inJustDecodeBounds = true;
    178.                 BitmapFactory.decodeFile(srcPath, options);
    179.                 return options;
    180.         }
    181.        
    182.         /**
    183.          * 获取图片缓存路径
    184.          * @param context
    185.          * @return
    186.          */
    187.         private static String getImageCacheDir(Context context) {
    188.                 String dir = FileHelper.getCacheDir(context) + "Image" + File.separator;
    189.                 File file = new File(dir);
    190.                 if (!file.exists()) file.mkdirs();
    191.                 return dir;
    192.         }
    193. }
    复制代码
    您需要登录后才可以回帖 登录 | 注册青鸟豆号

    本版积分规则

    Copyright 1999-2019 Beijing Aptech Beida Jade Bird Information Technology Co.,Ltd

    北大青鸟IT教育 北京阿博泰克北大青鸟信息技术有限公司 版权所有

    京ICP备11045574号-3 京公网安备11010802013845号

    快速回复 返回顶部 返回列表