Я пытаюсь создать программу обработки изображений в Android Studio, и у меня возникла проблема с сохранением растрового изображения.

Моя проблема заключается в сохранении изображения, полученного из ByteBuffer.

Чтобы показать это здесь, я сделал следующее: я загружаю изображение в ByteBuffer и пытаюсь сохранить его с масштабированием до 1014x1163 пикселей. И изображение, которое я получаю, искажено, неряшливо.

Например, вот изображение, которое я загружаю:

enter image description here

И вот что я получаю на изображении, которое я сохраняю:

enter image description here

Вот мой код:

imageSize = (int) (bmWidth*bmHeight*4);
ByteBuffer pixelsArray = ByteBuffer.allocateDirect(imageSize);
ByteBuffer outputArray = ByteBuffer.allocateDirect(imageSize);

workingBitmap.copyPixelsToBuffer(pixelsArray);
workingBitmap.copyPixelsToBuffer(outputArray);

int thiswidth   = workingBitmap.getWidth();
int thisheight  = workingBitmap.getHeight();

Bitmap copiedBitmap = Bitmap.createScaledBitmap(workingBitmap, Width, Height, false);

int thiswidth2   = copiedBitmap.getWidth();
int thisheight2  = copiedBitmap.getHeight();

outputArray.rewind();
copiedBitmap.copyPixelsFromBuffer(outputArray);
SaveJPG(copiedBitmap);

Функция SaveJPG работает нормально, потому что если я вызываю SaveJPG(workingBitmap), она сохраняет обычное изображение.

Вот код со значениями переменных во время отладки:

enter image description here

Мне интересно, возникает ли проблема из-за того, что выходное разрешение не кратно 4. Это обязательно в моей программе: разрешение выходного изображения может иметь любое значение (четное или нечетное).

Я пробовал много разных вещей (например, копирование рабочего битмапа и изменение размера копии).

Нет успеха. Я не знаю, в чем причина проблемы.

У кого-нибудь есть исходный код, который может сохранить изображение любого разрешения, хранящееся в ByteBuffer?

Заранее спасибо.

1
thomasp 3 Фев 2022 в 19:35
Даже если SaveJPG нормально работает с одним изображением, это не означает, что он работает правильно со всеми изображениями.
 – 
Robert
3 Фев 2022 в 19:44
Если изображение хранится в байтовом буфере, просто сохраните содержимое этого буфера на диск.
 – 
blackapps
3 Фев 2022 в 19:58

2 ответа

Попробуй это

try (FileOutputStream out = new FileOutputStream(yourFileName)) {
    yourBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
    // PNG is a lossless format, the compression factor (100) is ignored
} catch (IOException e) {
    e.printStackTrace();
}

Или используйте это

MediaStore.Images.Media.insertImage(getContentResolver(), yourbitmap,
    "File name", "description of the image");
1
Sambhav Khandelwal 3 Фев 2022 в 19:43
Спасибо за ваш ответ. Я уже пытался сохранить в PNG: та же проблема. Я пробовал ваше решение с использованием MediaStore.Images.Media.insertImage, но оно не работает: та же проблема (сохраненное изображение тоже искажено).
 – 
thomasp
3 Фев 2022 в 19:55
Тогда проблема с растровым изображением. позвольте мне проверить ваш код еще раз
 – 
Sambhav Khandelwal
3 Фев 2022 в 19:58
С чего грузить картинку? URI или URL или что-то еще?
 – 
Sambhav Khandelwal
3 Фев 2022 в 19:59
Я загружаю изображение из 2-х разных источников: из галереи или с камеры телефона. У меня такая же проблема с обоими источниками.
 – 
thomasp
3 Фев 2022 в 20:15
Если вы загружаете из галереи, она уже сохранена. Почему снова?
 – 
Sambhav Khandelwal
3 Фев 2022 в 20:16

Я нашел причину проблемы. Это было просто из-за проблемы с шириной и высотой входного изображения: я использовал ширину и высоту представления, которое отображает входное растровое изображение, вместо использования ширины и высоты растрового изображения.

0
thomasp 4 Фев 2022 в 00:28