Android - уменьшить размер файла изображения

У меня есть файл изображения URI, и я хочу уменьшить его размер. загрузить его. Начальный размер файла изображения зависит от мобильного устройства (может быть 2 МБ или 500 КБ), но я хочу, чтобы окончательный размер был около 200 КБ, чтобы я мог его загрузить.
Из того, что я прочитал, у меня есть (по крайней мере) 2 варианта:

  • Использование BitmapFactory.Options.inSampleSizeдля подвыборки исходного изображения и получения изображения меньшего размера;
  • Использование Bitmap.compressдля сжатия изображения с указанием качества сжатия.

Какой лучший выбор?


Я думал сначала изменить размер изображения по ширине/высоте до тех пор, пока ширина или высота не превысят 1000 пикселей (примерно 1024x768 или другие), а затем сжать изображение с уменьшением качества, пока размер файла не превысит 200 КБ. Вот пример:

int MAX_IMAGE_SIZE = 200 * 1024; // max final file size
Bitmap bmpPic = BitmapFactory.decodeFile(fileUri.getPath());
if ((bmpPic.getWidth() >= 1024) && (bmpPic.getHeight() >= 1024)) {
    BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
    bmpOptions.inSampleSize = 1;
    while ((bmpPic.getWidth() >= 1024) && (bmpPic.getHeight() >= 1024)) {
        bmpOptions.inSampleSize++;
        bmpPic = BitmapFactory.decodeFile(fileUri.getPath(), bmpOptions);
    }
    Log.d(TAG, "Resize: " + bmpOptions.inSampleSize);
}
int compressQuality = 104; // quality decreasing by 5 every loop. (start from 99)
int streamLength = MAX_IMAGE_SIZE;
while (streamLength >= MAX_IMAGE_SIZE) {
    ByteArrayOutputStream bmpStream = new ByteArrayOutputStream();
    compressQuality -= 5;
    Log.d(TAG, "Quality: " + compressQuality);
    bmpPic.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpStream);
    byte[] bmpPicByteArray = bmpStream.toByteArray();
    streamLength = bmpPicByteArray.length;
    Log.d(TAG, "Size: " + streamLength);
}
try {
    FileOutputStream bmpFile = new FileOutputStream(finalPath);
    bmpPic.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpFile);
    bmpFile.flush();
    bmpFile.close();
} catch (Exception e) {
    Log.e(TAG, "Error on saving file");
}

Есть ли лучший способ сделать это? Должен ли я продолжать использовать все 2 метода или только один? Спасибо

57
задан GAMA 16 June 2012 в 07:46
поделиться