Android - Skalieren und komprimieren Sie eine Bitmap

Ich arbeite an einer Android-App mit Kameraerfassung und Funktion zum Hochladen von Fotos. Wenn das Gerät über eine hochauflösende Kamera verfügt, ist das aufgenommene Bild sehr groß (1 bis 3 MB oder mehr).
Da die App dieses Bild auf den Server hochladen muss, muss ich das Bild vor dem Hochladen komprimieren. Wenn die Kamera zum Beispiel ein Foto mit einer Auflösung von 1920 x 1080 Pixeln aufnimmt, ist die ideale Ausgabe, ein 16: 9-Verhältnis des Bildes beizubehalten, es auf 640 x 360 Pixel zu komprimieren, um die Bildqualität zu verringern und es in Bytes kleiner zu machen.

Hier ist mein Code (von Google referenziert):

/**
 * this class provide methods that can help compress the image size.
 *
 */
public class ImageCompressHelper {

/**
 * Calcuate how much to compress the image
 * @param options
 * @param reqWidth
 * @param reqHeight
 * @return
 */
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
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;
}

/**
 * resize image to 480x800
 * @param filePath
 * @return
 */
public static Bitmap getSmallBitmap(String filePath) {

    File file = new File(filePath);
    long originalSize = file.length();

    MyLogger.Verbose("Original image size is: " + originalSize + " bytes.");

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, options);

    // Calculate inSampleSize based on a preset ratio
    options.inSampleSize = calculateInSampleSize(options, 480, 800);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    Bitmap compressedImage = BitmapFactory.decodeFile(filePath, options);

    MyLogger.Verbose("Compressed image size is " + sizeOf(compressedImage) + " bytes");

    return compressedImage;
}

Das Problem mit dem obigen Code ist:

Das Verhältnis kann nicht beibehalten werden. Der Code zwingt das Bild, die Größe auf 480 x 800 zu ändern. Wenn der Benutzer ein Bild in einem anderen Verhältnis aufgenommen hat, sieht das Bild nach dem Komprimieren nicht gut aus.

Es funktioniert nicht gut. Der Code ändert immer die Bildgröße in 7990272Byte, unabhängig von der ursprünglichen Dateigröße. Wenn das Originalbild bereits ziemlich klein ist, wird es groß (mein Testergebnis, um ein Bild von meiner Wand zu machen, die ziemlich einfarbig ist):

Original image size is: 990092 bytes.
Compressed image size is 7990272 bytes

Ich frage, ob es einen Vorschlag für eine bessere Methode zum Komprimieren von Fotos gibt, damit sie reibungslos hochgeladen werden können.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage