Это мой вариант использования:
ByteArray ba; // Some value is assigned here
Bitmap bitmap = BitmapFactory.decodeByteArray(ba, 0, ba.length);
Поскольку объект ByteArray
слишком велик, во второй строке возникает исключение OutOfMemoryError
при выполнении:
BitmapFactory.decodeByteArray(ba, 0, ba.length);
Уже пробовал:
ByteArray ba; // Some value is assigned here
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; //or whatever value
Bitmap bitmap = BitmapFactory.decodeByteArray(ba, 0, ba.length, options);
Проблема с этим решением заключается в том, что при использовании атрибута inSampleSize
исключается исключение OutOfMemoryError
, но размер битовая карта (размеры: ширина x высота) уменьшается.
Вместо этого я ищу что-то похожее на это:
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
В этом примере качественный растрового изображения уменьшено, НО его размер остается прежним. Когда я показываю это в ImageView
:
iv.setImageBitmap(bitmap);
Он занимает то же место, что и оригинал, но с половинным качеством.
Проблема в том, что в моем случае я не могу использовать bitmap.compress
, потому что мой битмап нулевой. То есть метод compress
можно использовать после у вас есть валидный Bitmap
объект, что не мой случай.
Вопрос:
Есть ли решение с использованием BitmapFactory.Options
, которое может привести к тому же результату, что и bitmap.compress
: меньше quality
, то же dimensions
?
Is there any solution using BitmapFactory.Options which can lead to the same result as bitmap.compress: lower quality, same dimensions?
Не совсем. Bitmap
несжатый по своей природе.
The problem is, that in my case I cannot use bitmap.compress because my bitmap is null.
Вы путаете закодированное изображение JPEG с Bitmap
. Закодированное изображение JPEG сжато. Bitmap
нет. Bitmap
всегда потребляет память в зависимости от ширины, высоты и количества битов на пиксель.
Вы можете использовать другое количество бит на пиксель. BitmapFactory
использует ARGB_8888
(32 бита на пиксель). Вы можете переключиться на RGB_565
(16 бит/пиксель), если ваше изображение не имеет альфа-канала и вы можете жить с уменьшенным диапазоном цветов.
В противном случае ваш единственный вариант — уменьшить размер (ширину и высоту) изображения.
Вы не можете сжимать растровое изображение так, как хотите.
Возможно, вы уже знаете это - Но, да! вы можете найти соответствующий inSampleSize этим методом, чтобы сохранить качество в зависимости от размера.
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;
}
Этот метод выбран из Android эффективно загружает большие изображения.
Вы можете прочитать больше о передаче Bimaps здесь
Это может быть хорошим решением в некоторых случаях. Переключение с
ARGB_888
наRGB_565
уменьшает размер более чем вдвое.