1

Also für jedes Bild habe ich seinen Pfad (in Form einer Zeichenfolge). Und ich wandle diese Pfadzeichenfolge in eine Datei um. Ich speichere dann diese Datei in Firebase-Speicher, aber mein Problem ist, dass die Datei zu groß ist, wenn ich abfrage. Also muss ich es komprimieren, bevor ich es Firebase-Speicher hochlade. Ich schaute mich um, fand aber nie eine klare Lösung dafür. Bitte, wenn mir jemand mit einer sehr klaren und einfachen Lösung helfen kann, wäre das toll. Unten ist mein Code.Wie komprimiere ich eine Bilddatei in 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

In welchem ​​Format werden Sie in db speichern Bild mit ?. Versuchen Sie, wenn möglich, das BLOB-Format zum Speichern des Bilds zu verwenden. Dadurch wird die Bildgröße automatisch auf KB reduziert. –

+0

ich benutze jpeg im moment. – TheQ

+0

ja. aber was ist das Format in db? ist es varchar oder int oder blob etc? –

Antwort

0

Hier ist, was Sie tun müssen:

Zuerst konvertieren Ihr Bild Bitmap:

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

Anstelle von 'logo' Ihre Imageview setzen. Dann

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; 
} 

Sie werden das Bild in Bytes in 'ByteImage' Variable speichern. Die Zahl '25' gibt an, wie viel Prozent Sie komprimieren möchten. In diesem Code wird die Größe des Bildes auf 25% reduziert. Versuchen Sie den Code und lassen Sie mich wissen :)

+0

Ja, es war in der Lage, die Dateigröße zu reduzieren. Wenn ich möchte, dass das Bild besonders 1024 x 1024 ist, wie würde ich das tun? – TheQ

+0

Sie möchten die Dateigröße reduzieren, ohne die Auflösung des Bildes zu reduzieren? –

+0

@TheQ Ich weiß nicht, ob das für Sie funktioniert, aber versuchen Sie es mit tinyPNG API, hier ist der Link [TinyPNG] (https://tinypng.com/developers) –

1

Ich habe eine benutzerdefinierte Klasse für Bildkomprimierung, die ich für Firebase Storage verwendet, und die Größe wurde deutlich reduziert.

Diese Klasse kann verwendet werden, können eine Bitmap zu komprimieren und auch eine Datei vor dem Senden

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

was würde ich ersetzen "MyApplication" – TheQ

+0

Das ist der Kontext, ich verwende den Anwendungskontext für diese –

+0

in meinem Fall, wenn ich ein Kontextobjekt und setzen Sie dieses Kontextobjekt in einem Konstruktor, würde das auch funktionieren? weil ich nicht auf den Anwendungskontext zugreifen kann, wie Sie es tun. – TheQ

0

Sie Größe Bitmap erforderlich folgenden Code erhalten zu Firebase,

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; 
} 

Aufruf decodeSampledBitmapFromArray mit Byte-Array Bitmap & erforderliche Breite & Höhe.

Folgenden sehen Sie die Art und Weise Sie Byte-Array von Bitmap erhalten können,

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; 
    } 
} 

Dadurch wird die Größe des Bildes komprimiert werden, tat aber nicht Größe ändern.

Dank dieser Antwort Compress bitmap in android

Verwandte Themen