1

因此,對於每個圖像我有它的路徑(以字符串的形式)。我將該路徑字符串轉換爲文件。然後我將該文件存儲到Firebase存儲中,但我的問題是查詢時文件太大。所以我需要在上傳Firebase存儲之前對其進行壓縮。我環顧四周,但從來沒有找到明確的解決方案,如何做到這一點。如果任何人都可以幫助我,那將會非常明確和簡單的解決方案。以下是我的代碼。如何在Android中壓縮圖像文件?

for(String path : images) 
{ 
    try { 
    InputStream stream = new FileInputStream(new File(path)); 
    UploadTask uploadTask = imageStorage.putStream(stream); 
    uploadTask.addOnFailureListener(new OnFailureListener() { 
     @Override 
     public void onFailure(@NonNull Exception exception) { 
      // Handle unsuccessful uploads 
      Log.d("myStorage","failure :("); 
     } 
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { 
     @Override 
     public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { 
      // taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL. 
      UrI downloadUrl = taskSnapshot.getDownloadUrl(); 
      Log.d("myStorage","success!"); 
     } 
    }); 
    } catch (FileNotFoundException e) { 
    e.printStackTrace(); 
    } 
    countDB++; 

} 
+0

?如果可能,請嘗試使用BLOB格式存儲圖像。這會自動將圖像大小減小到KB。 –

+0

即時使用jpeg。 – TheQ

+0

是的。但是什麼是db中的格式?它是varchar或int或blob等? –

回答

0

這裏是你必須做的:

首先,你的圖像轉換爲位圖:

Bitmap bitmap = ((BitmapDrawable) logo.getDrawable()).getBitmap(); 

代替 '標誌' 的把你的ImageView。然後,

byte[] byteImage = encodeToBase64(bitmap); 

public static byte[] encodeToBase64(Bitmap image) { 
    ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); 
    image.compress(Bitmap.CompressFormat.PNG, 25, byteArrayOS); 
    byte[] byteArray = byteArrayOS.toByteArray(); 
    return byteArray; 
} 

您將在'byteImage'變量中以字節存儲圖像。數字「25」是你想壓縮多少百分比。在這段代碼中,它將圖像的大小縮小到25%。試試代碼,並讓我知道:)

+0

是的,它能夠減小文件大小。如果我想要圖像特別是1024 x 1024,我該怎麼做? – TheQ

+0

想要減小文件大小而不降低圖像分辨率? –

+0

@TheQ我不知道這是否適用於您,但嘗試使用tinyPNG API,這裏是鏈接[TinyPNG](https://tinypng.com/developers) –

1

我有一個用於Firebase存儲的圖像壓縮的自定義類,並且大小顯着減小。

這個類可以用來壓縮位圖,也是一個文件發送之前火力

public class ImageCompression { 

public static Bitmap getThumbnail(Uri uri, Context context) throws FileNotFoundException, IOException { 
    InputStream input = context.getContentResolver().openInputStream(uri); 

    BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options(); 
    onlyBoundsOptions.inJustDecodeBounds = true; 
    onlyBoundsOptions.inDither = true;//optional 
    onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional 
    BitmapFactory.decodeStream(input, null, onlyBoundsOptions); 
    input.close(); 
    if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1)) 
     return null; 

    int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth; 

    double ratio = (originalSize > 500) ? (originalSize/500) : 1.0; 

    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); 
    bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio); 
    bitmapOptions.inDither = true;//optional 
    bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional 
    input = context.getContentResolver().openInputStream(uri); 
    Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions); 
    input.close(); 
    return bitmap; 
} 

private static int getPowerOfTwoForSampleRatio(double ratio) { 
    int k = Integer.highestOneBit((int) Math.floor(ratio)); 
    if (k == 0) return 1; 
    else return k; 
} 

public static File compressFile(File file, Context context) { 
    try { 

     // BitmapFactory options to downsize the image 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     o.inSampleSize = 6; 
     // factor of downsizing the image 

     FileInputStream inputStream = new FileInputStream(file); 
     //Bitmap selectedBitmap = null; 
     BitmapFactory.decodeStream(inputStream, null, o); 
     inputStream.close(); 

     // The new size we want to scale to 
     final int REQUIRED_SIZE = 75; 

     // Find the correct scale value. It should be the power of 2. 
     int scale = 1; 
     while (o.outWidth/scale/2 >= REQUIRED_SIZE && 
       o.outHeight/scale/2 >= REQUIRED_SIZE) { 
      scale *= 2; 
     } 

     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     inputStream = new FileInputStream(file); 

     Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2); 
     inputStream.close(); 

     // here i override the original image file 
     file.createNewFile(); 
     FileOutputStream outputStream = new FileOutputStream(file); 

     selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outputStream); 

     return file; 
    } catch (Exception e) { 
     return null; 
    } 
} 
} 



ImageCompression.compressFile(YourFile, this); 
ImageCompression.getThumbnail(YourUri, this); 
+0

我會用什麼替代「MyApplication」 – TheQ

+0

這就是上下文,在我的情況下,我使用應用程序上下文來處理這個 –

+0

,如果我創建了一個上下文對象並在構造函數中設置了該上下文對象,那麼它也可以工作嗎?因爲我無法像使用相同的方式訪問應用程序上下文。 – TheQ

0

您可以使用下面的代碼獲得所需大小的位圖,

public static Bitmap decodeSampledBitmapFromArray(byte[] data, int reqWidth, int reqHeight) { 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeByteArray(data, 0, data.length, options); 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeByteArray(data, 0, data.length, options); 
} 

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 
    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) >= reqHeight 
       && (halfWidth/inSampleSize) >= reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 
    return inSampleSize; 
} 

呼叫decodeSampledBitmapFromArray與字節數組位圖&所需寬度&高度。

以下是你可以從位圖字節數組的方式,

Bitmap bmp = Your_bitmap; 
ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); 
byte[] byteArray = stream.toByteArray(); 
0
ImageView imageView = (ImageView)findViewById(R.id.imageView); 
Bitmap bitmap = ImageUtils.getInstant().getCompressedBitmap("Your_Image_Path_Here"); 
imageView.setImageBitmap(bitmap); 

ImageUtils.java:

public class ImageUtils { 

    public static ImageUtils mInstant; 

    public static ImageUtils getInstant(){ 
     if(mInstant==null){ 
      mInstant = new ImageUtils(); 
     } 
     return mInstant; 
    } 

    public Bitmap getCompressedBitmap(String imagePath) { 
     float maxHeight = 1920.0f; 
     float maxWidth = 1080.0f; 
     Bitmap scaledBitmap = null; 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     Bitmap bmp = BitmapFactory.decodeFile(imagePath, options); 

     int actualHeight = options.outHeight; 
     int actualWidth = options.outWidth; 
     float imgRatio = (float) actualWidth/(float) actualHeight; 
     float maxRatio = maxWidth/maxHeight; 

     if (actualHeight > maxHeight || actualWidth > maxWidth) { 
      if (imgRatio < maxRatio) { 
       imgRatio = maxHeight/actualHeight; 
       actualWidth = (int) (imgRatio * actualWidth); 
       actualHeight = (int) maxHeight; 
      } else if (imgRatio > maxRatio) { 
       imgRatio = maxWidth/actualWidth; 
       actualHeight = (int) (imgRatio * actualHeight); 
       actualWidth = (int) maxWidth; 
      } else { 
       actualHeight = (int) maxHeight; 
       actualWidth = (int) maxWidth; 

      } 
     } 

     options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight); 
     options.inJustDecodeBounds = false; 
     options.inDither = false; 
     options.inPurgeable = true; 
     options.inInputShareable = true; 
     options.inTempStorage = new byte[16 * 1024]; 

     try { 
      bmp = BitmapFactory.decodeFile(imagePath, options); 
     } catch (OutOfMemoryError exception) { 
      exception.printStackTrace(); 

     } 
     try { 
      scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888); 
     } catch (OutOfMemoryError exception) { 
      exception.printStackTrace(); 
     } 

     float ratioX = actualWidth/(float) options.outWidth; 
     float ratioY = actualHeight/(float) options.outHeight; 
     float middleX = actualWidth/2.0f; 
     float middleY = actualHeight/2.0f; 

     Matrix scaleMatrix = new Matrix(); 
     scaleMatrix.setScale(ratioX, ratioY, middleX, middleY); 

     Canvas canvas = new Canvas(scaledBitmap); 
     canvas.setMatrix(scaleMatrix); 
     canvas.drawBitmap(bmp, middleX - bmp.getWidth()/2, middleY - bmp.getHeight()/2, new Paint(Paint.FILTER_BITMAP_FLAG)); 

     ExifInterface exif = null; 
     try { 
      exif = new ExifInterface(imagePath); 
      int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); 
      Matrix matrix = new Matrix(); 
      if (orientation == 6) { 
       matrix.postRotate(90); 
      } else if (orientation == 3) { 
       matrix.postRotate(180); 
      } else if (orientation == 8) { 
       matrix.postRotate(270); 
      } 
      scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, out); 

     byte[] byteArray = out.toByteArray(); 

     Bitmap updatedBitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 

     return updatedBitmap; 
    } 

    private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
     final int height = options.outHeight; 
     final int width = options.outWidth; 
     int inSampleSize = 1; 

     if (height > reqHeight || width > reqWidth) { 
      final int heightRatio = Math.round((float) height/(float) reqHeight); 
      final int widthRatio = Math.round((float) width/(float) reqWidth); 
      inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
     } 
     final float totalPixels = width * height; 
     final float totalReqPixelsCap = reqWidth * reqHeight * 2; 

     while (totalPixels/(inSampleSize * inSampleSize) > totalReqPixelsCap) { 
      inSampleSize++; 
     } 
     return inSampleSize; 
    } 
} 

這將壓縮圖像的大小,但沒有調整它的大小。

感謝您使用存儲在數據庫圖像格式是什麼這個答案Compress bitmap in android