У меня есть файл изображения 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 метода или только один? Благодаря