Android 圖片壓縮處理

android 圖片上傳前壓縮


參考:https://github.com/guizhigang/LGImageCompressor

詳解:

  • 1.獲取本地圖片F(xiàn)ile文件 獲取BitmapFactory.Options對(duì)象 計(jì)算原始圖片 目標(biāo)圖片寬高比 計(jì)算輸出的圖片寬高

  • 2.根據(jù)寬高比計(jì)算options.inSampleSize值(縮放比例 If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.)得到bitmap位圖 根據(jù)位圖對(duì)象獲取新的輸出位圖對(duì)象 Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)Creates a new bitmap, scaled from an existing bitmap, whenpossible.

  • 3.獲取圖片方向調(diào)整、失量壓縮圖片保持在1024kb以下

      //進(jìn)行大小縮放來(lái)達(dá)到壓縮的目的
      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inJustDecodeBounds = true;
      BitmapFactory.decodeFile(srcImagePath, options);
      //根據(jù)原始圖片的寬高比和期望的輸出圖片的寬高比計(jì)算最終輸出的圖片的寬和高
    
      float srcWidth = options.outWidth;
      float srcHeight = options.outHeight;
      float maxWidth = outWidth;
      float maxHeight = outHeight;
      float srcRatio = srcWidth / srcHeight; //原始圖片寬高比
      float outRatio = maxWidth / maxHeight; //目標(biāo)圖片寬高比
      float actualOutWidth = srcWidth;
      float actualOutHeight = srcHeight;
       if (srcWidth > maxWidth || srcHeight > maxHeight) {
          if(srcRatio>outRatio){ //原始寬高比大于目標(biāo)寬高比
              actualOutWidth = maxWidth;
              actualOutHeight = actualOutWidth / srcRatio;
          }else if(srcRatio<outRatio){ //原始寬高比小于目標(biāo)寬高比
              actualOutHeight = maxHeight;
              actualOutWidth = actualOutHeight * srcRatio;
          }
      }else{
          actualOutWidth = maxWidth;
          actualOutHeight = maxHeight;
      }
    
      options.inSampleSize = computSampleSize(options, actualOutWidth, actualOutHeight);
      options.inJustDecodeBounds = false;
      Bitmap scaledBitmap = null;
      try {
          scaledBitmap = BitmapFactory.decodeFile(srcImagePath, options);
      } catch (OutOfMemoryError e) {
          e.printStackTrace();
      }
      if (scaledBitmap == null) {
          return null;
      }
      
        //生成最終輸出的bitmap
      Bitmap actualOutBitmap = Bitmap.createScaledBitmap(scaledBitmap, (int) actualOutWidth, (int) actualOutHeight, true);
      
      //釋放原始位圖資源
      if(scaledBitmap!=actualOutBitmap){ //判斷目標(biāo)位圖是否和原始位圖指向棧目標(biāo)相同
          scaledBitmap.recycle();
          scaledBitmap = null;
      }
      
       //處理圖片旋轉(zhuǎn)問(wèn)題
      ExifInterface exif = null;
      try {
          exif = new ExifInterface(srcImagePath);
          int orientation = exif.getAttributeInt(
                  ExifInterface.TAG_ORIENTATION, 0);
          Matrix matrix = new Matrix();
          if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
              matrix.postRotate(90);
          } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
              matrix.postRotate(180);
          } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
              matrix.postRotate(270);
          }
          actualOutBitmap = Bitmap.createBitmap(actualOutBitmap, 0, 0,
                  actualOutBitmap.getWidth(), actualOutBitmap.getHeight(), matrix, true);
      } catch (IOException e) {
          e.printStackTrace();
          return null;
      }
    
       //進(jìn)行有損壓縮
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      int options_ = 100;
      actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//質(zhì)量壓縮方法,把壓縮后的數(shù)據(jù)存放到baos中 (100表示不壓縮,0表示壓縮到最小)
    
      int baosLength = baos.toByteArray().length;
    
      while (baosLength / 1024 > maxFileSize) {//循環(huán)判斷如果壓縮后圖片是否大于maxMemmorrySize,大于繼續(xù)壓縮
          baos.reset();//重置baos即讓下一次的寫入覆蓋之前的內(nèi)容
          options_ = Math.max(0, options_ - 10);//圖片質(zhì)量每次減少10
          actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//將壓縮后的圖片保存到baos中
          baosLength = baos.toByteArray().length;
          if (options_ == 0)//如果圖片的質(zhì)量已降到最低則,不再進(jìn)行壓縮
              break;
      }
      actualOutBitmap.recycle();
    
      //將bitmap保存到指定路徑
      FileOutputStream fos = null;
      String filePath = getOutputFileName(srcImagePath);
      try {
          fos = new FileOutputStream(filePath);
          //包裝緩沖流,提高寫入速度
          BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fos);
          bufferedOutputStream.write(baos.toByteArray());
          bufferedOutputStream.flush();
      } catch (FileNotFoundException e) {
          return null;
      } catch (IOException e) {
          return null;
      } finally {
          if (baos != null) {
              try {
                  baos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          if (fos != null) {
              try {
                  fos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
    
      //獲取位圖縮放比例
      private int computSampleSize(BitmapFactory.Options options, float reqWidth, float reqHeight) {
          float srcWidth = options.outWidth;//20
          float srcHeight = options.outHeight;//10
          int sampleSize = 1;
          if (srcWidth > reqWidth || srcHeight > reqHeight) {
              int withRatio = Math.round(srcWidth / reqWidth);
              int heightRatio = Math.round(srcHeight / reqHeight);
              sampleSize = Math.min(withRatio, heightRatio);
          }
          return sampleSize;
      }
    

壓縮比例換算:

float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
float widthScale = outWidth / srcWidth;//目標(biāo)/原始 寬比例
float heightScale = outHeight / srcHeight; //目標(biāo)原始 高比
//對(duì)比寬高比選擇較大的一種比例
float scale = widthScale > heightScale ? widthScale : heightScale;
float actualOutWidth = srcWidth;
float actualOutHeight = srcHeight;
if (scale < 1) {
    actualOutWidth = srcWidth * scale;
    actualOutHeight = srcHeight * scale;
}

設(shè)置縮放比例--生成新的位圖

    Matrix matrix1 = new Matrix();
    matrix1.postScale(scale, scale);// 放大縮小比例
    //生成最終輸出的bitmap
    Bitmap actualOutBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix1, true);

    if (actualOutBitmap != scaledBitmap) {
        scaledBitmap.recycle();
        scaledBitmap = null;
        System.gc();
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容