Android图片压缩的几种方式

图片的几种压缩方式总结

实际项目中,对图片的压缩处理相当常见,下面总结几种压缩的方式:

  • 只压缩质量的方式:
  /** * 只压缩质量的方法 * @param file 源文件 * @param targetPath 目标路径 * @param quality 质量 取值为0-100 100表示按最大质量,此参数对PNG图片无效,即compress方法的第一个参数为 * Bitmap.CompressFormat.PNG时,quality的设置是无效的。 * **/
   public static File scalFile(File file, String targetPath,int quality){
        try {
                //将文件转换为字节数组
                byte[] bytes = getBytesFromFile(file);
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = false;
                Bitmap bitmap=BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
                if(bitmap != null){
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);  
                    baos.close();
                    File targetFile = new File(targetPath);
                if(targetFile.exists()){
                        boolean flag = targetFile.delete();
                        Log.i("ImageUtils.scalFile()", "flag: " + flag);
                    }
                    FileOutputStream fos = new FileOutputStream(targetFile);
                    fos.write(baos.toByteArray());
                    fos.flush();
                    fos.close();
                    return targetFile;
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("ImageUtils.scalFile()",e.getMessage());
            }
            return null;
    }
  • 压缩到指定分辨率的方式:例从任意分辨率压缩到1280X960或960X1280,以矩阵缩放的方式达到目的,宽高分别取相应的比例去与目标宽高达成一致
   /** * 压缩到指定分辨率的方法 以1280X960为例 * @param file 源文件 * @param targetPath 目标路径 * * * **/
   public static File scalFile(File file, String targetPath){
        long fileSize = file.length();
        final long fileMaxSize = 200 * 1024;//超过200K的图片需要进行压缩
        if(fileSize > fileMaxSize){
            try {
                byte[] bytes = getBytesFromFile(file);//将文件转换为字节数组
                BitmapFactory.Options options = new BitmapFactory.Options();
                //仅仅解码边缘区域
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
                //得到宽高
                int width = options.outWidth;
                int height = options.outHeight;
                float scaleWidth=0f;
                float scaleHeight=0f;
                Matrix matrix=new Matrix();
                if(width>height)
                {
                    scaleWidth=(float)1280/width;
                    scaleHeight=(float)960/height;

                }else{
                    scaleWidth=(float)960/width;
                    scaleHeight=(float)1280/height;
                }
                Bitmap bitmap=BitmapFactory.decodeFile(file.getPath());
                matrix.postScale(scaleWidth, scaleHeight);//执行缩放
                Bitmap resizeBitmap=Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
                if(resizeBitmap != null){
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                    int quality = 100;  
                    resizeBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
                                //限制压缩后图片最大为200K,否则继续压缩
                    while (baos.toByteArray().length > fileMaxSize) {   
                        baos.reset();  
                        quality -= 10;  
                        resizeBitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
                    }  
                    baos.close();
                    File targetFile = new File(targetPath);
                    if(targetFile.exists()){
                        boolean flag = targetFile.delete();
                        Log.i("ImageUtils.scalFile()", "flag: " + flag);
                    }
                    FileOutputStream fos = new FileOutputStream(targetFile);
                    fos.write(baos.toByteArray());
                    fos.flush();
                    fos.close();
                    return targetFile;
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("ImageUtils.scalFile()",e.getMessage());
            }
            return null;
        }else{
            return file;
        }
    }
  • 等比例压缩方式1:这种是用采样率的方式来等比例的缩小,优点是同等条件下会清晰一点,缺点是无法按计算得到的比例去缩小
    ,因为根据官方说明sampleSize为2的幂时,效果较好,而根据实测,发现其取值会趋向于2的幂,比如sampleSize为4到8之间的值,会均按4来缩小
  /*** *等比例压缩方式1,以采样率的方式,以1280X960为例 *@param file 源文件 *@param targetPath 目标路径 * **/
   public static File scalFile(File file, String targetPath){
    long fileSize = file.length();
        final long fileMaxSize = 200 * 1024;
        if(fileSize > fileMaxSize){
            try {
            byte[] bytes = getBytesFromFile(file);//将文件转换为字节数组
            BitmapFactory.Options options = new BitmapFactory.Options();
                //仅仅解码边缘区域
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
                //得到宽高
                int width = options.outWidth;
                int height = options.outHeight;
                int sampleSize =1;
                if(width>height)
                {       
                sampleSize=Math.max(width/1280, height/960);
                }else{  
                sampleSize=Math.max(width/960, height/1280);
                }
                if(sampleSize < 1)
                sampleSize = 1;             
                //不再加载图片边缘
                options.inJustDecodeBounds = false;
                //制定缩放比例
                options.inSampleSize = sampleSize;
                Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
                if(bitmap != null){
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                    int quality = 100;  
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);                    
                    while (baos.toByteArray().length > fileMaxSize) {   
                        baos.reset();  
                        quality -= 10;  
                        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);                    
                    }  
                    baos.close();
                   File targetFile = new File(targetPath);
            if(targetFile.exists()){
            boolean flag = targetFile.delete();
            Log.i("ImageUtils.scalFile()", "flag: " + flag);
            }
            FileOutputStream fos = new FileOutputStream(targetFile);
            fos.write(baos.toByteArray());
            fos.flush();
            fos.close();
            return targetFile;
                }
        } catch (Exception e) {
                e.printStackTrace();
                Log.i("ImageUtils.scalFile()",e.getMessage());
            }
            return null;
        }else{
            return file;
    }
    }
  • 等比例压缩方式2:这种是采用矩阵缩放的方式来等比例缩放,首先计算取得一个合适的比例,然后宽高取同一个比例,进行缩放。优点是可以压缩任意一个比例,不像”等比例压缩方式1”只局限于2的幂,无法压缩指定的倍数,缺点是虽然压缩后的图片比”等比例压缩方式 1”得到的图片小,但也没有小多少,但质量远远不如。
  /** * 等比例压缩方式2 以1280X960为例 * @param file 源文件 * @param targetPath 目标路径 * * ***/
  public static File scalFile(File file, String targetPath){
        long fileSize = file.length();
        final long fileMaxSize = 200 * 1024;
        if(fileSize > fileMaxSize){
            try {
                byte[] bytes = getBytesFromFile(file);//将文件转换为字节数组
                BitmapFactory.Options options = new BitmapFactory.Options();
                //仅仅解码边缘区域
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
                //得到宽高
                int width = options.outWidth;
                int height = options.outHeight;
                float scaleWidth=0f;
                float scaleHeight=0f;
                float scale=0f;
                Matrix matrix=new Matrix();
                if(width>height)
                {
                scaleWidth=(float)1280/width;
                scaleHeight=(float)960/height;
                }else{
                scaleWidth=(float)960/width;
                scaleHeight=(float)1280/height;
                }
                        //取两者之间较大的比例,这是为了尽可能得到分辨率大的图片
                scale=Math.max(scaleWidth, scaleHeight);
                Bitmap bitmap=BitmapFactory.decodeFile(file.getPath());
                matrix.postScale(scale, scale);
                Bitmap resizeBitmap=Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
                if(resizeBitmap != null){
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                    int quality = 100;  
                    resizeBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
                    while (baos.toByteArray().length > fileMaxSize) {   
                        baos.reset();  
                        quality -= 10;  
                        resizeBitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos); 
                    }  
                    baos.close();
                    File targetFile = new File(targetPath);
                    if(targetFile.exists()){
                        boolean flag = targetFile.delete();
                        Log.i("ImageUtils.scalFile()", "flag: " + flag);
                    }
                    FileOutputStream fos = new FileOutputStream(targetFile);
                    fos.write(baos.toByteArray());
                    fos.flush();
                    fos.close();
                    return targetFile;
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("ImageUtils.scalFile()",e.getMessage());
            }
            return null;
        }else{
            return file;
        }
    }

你可能感兴趣的:(安卓图片压缩)