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;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值