天天看点

Android一种高效压缩图片的方法

公司项目中有一个功能,就是用户能够上传图片到我们的服务器中,图片可以是用户本地图片,也可以是用户拍摄的照片。这些图片不受我们控制,有些照片可能很大,比如手机相机拍摄的,大小都是几兆的,用户直接上传这么大的图片肯定是不行的,网速慢的话上传很耗时,而且在非WIFI情况下,肯定要消耗用户大量的流量。

所以,我们需要把用户选择的图片先压缩,然后再上传。下面将介绍一个高效的图片压缩方法,基本上能够把几兆的图片压缩到几百KB甚至100KB以下,而且不失真,以SD卡下/big_images目录中的一个图片为例,这个图片是手机拍摄的,大小为3.1M。

Android一种高效压缩图片的方法

一、判断图片大小

上传图片时,先判断图片的大小,如果图片大小于1M的话,就不需要压缩了,可以直接上传;当图片大于1M的话在就行压缩。

[java]  view plain  copy  

Android一种高效压缩图片的方法
Android一种高效压缩图片的方法
  1. // SD卡根目录路径  
  2. sdCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();  
  3. // 需要判断大小的图片路径  
  4. String bigImage = sdCardPath + "/test_images/big.jpg";  
  5. // 获取指定文件的指定单位的大小  param1:文件路径  param2:获取大小的类型  1为B、2为KB、3为MB、4为GB  
  6. double bigSize = FileSizeUtil.getFileOrFilesSize(bigImage, 3);  
  7. tv_big.setText("图片压缩前的大小为:" + bigSize + "MB");  

二、压缩图片

[java]  view plain  copy  

Android一种高效压缩图片的方法
Android一种高效压缩图片的方法
  1. // 当图片大于1M时,才进行压缩  
  2. String smallImage;  
  3. if (bigSize > 1){   
  4. smallImage = compress(bigImage);  
  5. } else {  
  6. smallImage = bigImage;  
  7. }  
  8. double smallSize = FileSizeUtil.getFileOrFilesSize(smallImage, 2);  
  9. tv_small.setText("图片压缩后的大小为:" + smallSize + "KB");  

compress方法:

[java]  view plain  copy  

Android一种高效压缩图片的方法
Android一种高效压缩图片的方法
  1. private String compress(String path) {  
  2. if (path != null) {  
  3. try {  
  4. File file = new File(path);  
  5.             Bitmap bm = PictureUtil.getSmallBitmap(path);  
  6.             String sdCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();  
  7.             String dirPath = sdCardPath + "/test_images/";  
  8.             FileOutputStream fos = new FileOutputStream(new File( dirPath,"small.jpg"));  
  9.             bm.compress(Bitmap.CompressFormat.JPEG, 40, fos);  
  10.             String newPath = dirPath + "small.jpg";  
  11.             return newPath;  
  12.         } catch (Exception e) {  
  13.         }  
  14.     }  
  15.     return path;  
  16. }  

其中需要用到两个工具类:

1.FileSizeUtil.java

[java]  view plain  copy  

Android一种高效压缩图片的方法
Android一种高效压缩图片的方法
  1. public class FileSizeUtil {  
  2.     public static final int SIZETYPE_B = 1;// 获取文件大小单位为B的double值  
  3.     public static final int SIZETYPE_KB = 2;// 获取文件大小单位为KB的double值  
  4.     public static final int SIZETYPE_MB = 3;// 获取文件大小单位为MB的double值  
  5.     public static final int SIZETYPE_GB = 4;// 获取文件大小单位为GB的double值  
  6.     public static double getFileOrFilesSize(String filePath, int sizeType) {  
  7.         File file = new File(filePath);  
  8.         long blockSize = 0;  
  9.         try {  
  10.             if (file.isDirectory()) {  
  11.                 blockSize = getFileSizes(file);  
  12.             } else {  
  13.                 blockSize = getFileSize(file);  
  14.             }  
  15.         } catch (Exception e) {  
  16.             e.printStackTrace();  
  17.             Log.e("获取文件大小", "获取失败!");  
  18.         }  
  19.         return FormetFileSize(blockSize, sizeType);  
  20.     }  
  21.     public static String getAutoFileOrFilesSize(String filePath) {  
  22.         File file = new File(filePath);  
  23.         long blockSize = 0;  
  24.         try {  
  25.             if (file.isDirectory()) {  
  26.                 blockSize = getFileSizes(file);  
  27.             } else {  
  28.                 blockSize = getFileSize(file);  
  29.             }  
  30.         } catch (Exception e) {  
  31.             e.printStackTrace();  
  32.             Log.e("获取文件大小", "获取失败!");  
  33.         }  
  34.         return FormetFileSize(blockSize);  
  35.     }  
  36.     private static long getFileSize(File file) throws Exception {  
  37.         long size = 0;  
  38.         if (file.exists()) {  
  39.             FileInputStream fis = null;  
  40.             fis = new FileInputStream(file);  
  41.             size = fis.available();  
  42.         } else {  
  43.             file.createNewFile();  
  44.             Log.e("获取文件大小", "文件不存在!");  
  45.         }  
  46.         return size;  
  47.     }  
  48.     private static long getFileSizes(File f) throws Exception {  
  49.         long size = 0;  
  50.         File flist[] = f.listFiles();  
  51.         for (int i = 0; i < flist.length; i++) {  
  52.             if (flist[i].isDirectory()) {  
  53.                 size = size + getFileSizes(flist[i]);  
  54.             } else {  
  55.                 size = size + getFileSize(flist[i]);  
  56.             }  
  57.         }  
  58.         return size;  
  59.     }  
  60.     private static String FormetFileSize(long fileS) {  
  61.         DecimalFormat df = new DecimalFormat("#.00");  
  62.         String fileSizeString = "";  
  63.         String wrongSize = "0B";  
  64.         if (fileS == 0) {  
  65.             return wrongSize;  
  66.         }  
  67.         if (fileS < 1024) {  
  68.             fileSizeString = df.format((double) fileS) + "B";  
  69.         } else if (fileS < 1048576) {  
  70.             fileSizeString = df.format((double) fileS / 1024) + "KB";  
  71.         } else if (fileS < 1073741824) {  
  72.             fileSizeString = df.format((double) fileS / 1048576) + "MB";  
  73.         } else {  
  74.             fileSizeString = df.format((double) fileS / 1073741824) + "GB";  
  75.         }  
  76.         return fileSizeString;  
  77.     }  
  78.     private static double FormetFileSize(long fileS, int sizeType) {  
  79.         DecimalFormat df = new DecimalFormat("#.00");  
  80.         double fileSizeLong = 0;  
  81.         switch (sizeType) {  
  82.         case SIZETYPE_B:  
  83.             fileSizeLong = Double.valueOf(df.format((double) fileS));  
  84.             break;  
  85.         case SIZETYPE_KB:  
  86.             fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));  
  87.             break;  
  88.         case SIZETYPE_MB:  
  89.             fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));  
  90.             break;  
  91.         case SIZETYPE_GB:  
  92.             fileSizeLong = Double.valueOf(df.format((double) fileS / 1073741824));  
  93.             break;  
  94.         default:  
  95.             break;  
  96.         }  
  97.         return fileSizeLong;  
  98.     }  
  99. }  

2.PictureUtil.java

[java]  view plain  copy  

Android一种高效压缩图片的方法
Android一种高效压缩图片的方法
  1. public class PictureUtil {  
  2.     public static String bitmapToString(String filePath) {  
  3.         Bitmap bm = getSmallBitmap(filePath);  
  4.         ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  5.         bm.compress(Bitmap.CompressFormat.JPEG, 40, baos);  
  6.         byte[] b = baos.toByteArray();  
  7.         return Base64.encodeToString(b, Base64.DEFAULT);  
  8.     }  
  9.     public static int calculateInSampleSize(BitmapFactory.Options options,  
  10.             int reqWidth, int reqHeight) {  
  11.         // Raw height and width of image  
  12.         final int height = options.outHeight;  
  13.         final int width = options.outWidth;  
  14.         int inSampleSize = 1;  
  15.         if (height > reqHeight || width > reqWidth) {  
  16.             // Calculate ratios of height and width to requested height and  
  17.             // width  
  18.             final int heightRatio = Math.round((float) height / (float) reqHeight);  
  19.             final int widthRatio = Math.round((float) width / (float) reqWidth);  
  20.             // Choose the smallest ratio as inSampleSize value, this will  
  21.             // guarantee  
  22.             // a final image with both dimensions larger than or equal to the  
  23.             // requested height and width.  
  24.             inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;  
  25.         }  
  26.         return inSampleSize;  
  27.     }  
  28.     public static Bitmap getSmallBitmap(String filePath) {  
  29.         final BitmapFactory.Options options = new BitmapFactory.Options();  
  30.         options.inJustDecodeBounds = true;  
  31.         BitmapFactory.decodeFile(filePath, options);  
  32.         // Calculate inSampleSize  
  33.         options.inSampleSize = calculateInSampleSize(options, 480, 800);  
  34.         // Decode bitmap with inSampleSize set  
  35.         options.inJustDecodeBounds = false;  
  36.         return BitmapFactory.decodeFile(filePath, options);  
  37.     }  
  38.     public static void deleteTempFile(String path) {  
  39.         File file = new File(path);  
  40.         if (file.exists()) {  
  41.             file.delete();  
  42.         }  
  43.     }  
  44.     public static void galleryAddPic(Context context, String path) {  
  45.         Intent mediaScanIntent = new Intent(  
  46.                 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);  
  47.         File f = new File(path);  
  48.         Uri contentUri = Uri.fromFile(f);  
  49.         mediaScanIntent.setData(contentUri);  
  50.         context.sendBroadcast(mediaScanIntent);  
  51.     }  
  52.     public static File getAlbumDir() {  
  53.         File dir = new File(  
  54.                 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),  
  55.                 getAlbumName());  
  56.         if (!dir.exists()) {  
  57.             dir.mkdirs();  
  58.         }  
  59.         return dir;  
  60.     }  
  61.     public static String getAlbumName() {  
  62.         return "sheguantong";  
  63.     }  
  64. }  

别忘了添加读写SD卡的权限,不然会报错。 [html]  view plain  copy  

Android一种高效压缩图片的方法
Android一种高效压缩图片的方法
  1. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>  
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>