Android - skaluj i kompresuj mapę bitową

Pracuję nad aplikacją na Androida, która ma funkcję przechwytywania i przesyłania zdjęć. Jeśli urządzenie ma kamerę o wysokiej rozdzielczości, rozmiar przechwyconego obrazu będzie naprawdę duży (1–3 MB lub więcej).
Ponieważ aplikacja będzie musiała przesłać ten obraz na serwer, muszę go skompresować przed przesłaniem. Jeśli na przykład kamera przechwyciła zdjęcie o pełnej rozdzielczości 1920x1080, idealnym wyjściem jest zachowanie proporcji obrazu 16: 9, skompresowanie go do obrazu 640x360 w celu zmniejszenia jakości obrazu i zmniejszenie go w bajtach.

Oto mój kod (przywoływany z google):

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

Problem z powyższym kodem to:

Nie może utrzymać proporcji, kod wymusza zmianę rozmiaru obrazu na 480x800. jeśli użytkownik przechwycił obraz w innym stosunku, obraz nie będzie wyglądał dobrze po kompresji.

Nie działa dobrze. Kod zawsze zmieni rozmiar obrazu na 7990272 bajtów, niezależnie od oryginalnego rozmiaru pliku. Jeśli rozmiar oryginalnego obrazu jest już dość mały, będzie on duży (mój wynik testu do zrobienia zdjęcia mojej ściany, która jest prawie jednokolorowa):

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

Pytam, czy jest sugestia lepszego sposobu kompresji zdjęć, aby można je było ładnie załadować?

questionAnswers(2)

yourAnswerToTheQuestion