Android или Java. Уменьшить размер изображения без (с минимальной) потери качества

182
10 февраля 2019, 02:30

Делаю фото в разрешении 1440x1080. Использую следующий код, что бы развернуть если необходимо изображение, обрезать квадрат, и уменьшить его до 1000x1000. После всех этих операций качество фото при увеличении получается не очень, при том, что камера телефона очень хорошая (и родная камера делает фотографии отличные, но там разрешение 4000x3000).

Верно ли, что есть разные алгоритмы и подходы к сжатию/уменьшению изображений? Если да, то - верно ли что стандартные средства android сжимают и уменьшают изображения не самым оптимальным способом?

Можно ли качественнее сжать и уменьшить фото на android?

Bitmap bm = BitmapFactory.decodeByteArray((byte[]) data, 0, data.length);
Matrix matrix = new Matrix();
matrix.postRotate(getRotateAngle());
int width = camera.getParameters().getPictureSize().width;
int height = camera.getParameters().getPictureSize().height;
int croppedWidth = width > height ? height : width;
bm = Bitmap.createBitmap(bm, 0, 0, croppedWidth, croppedWidth, matrix, true);
if (croppedWidth >= 1000) {
   bm = Bitmap.createScaledBitmap(bm, 1000, 1000, false);
} else {
   bm = Bitmap.createScaledBitmap(bm, croppedWidth, croppedWidth, false);
}
File outputDir = context.getCacheDir(); 
File outputFile = File.createTempFile("prefix", "extension", outputDir);
FileOutputStream fos = new FileOutputStream(outFile);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
img.compress(Bitmap.CompressFormat.JPEG, 100, stream); 
fos.write(stream.toByteArray());
fos.close();
Answer 1

Пример сжатия взял с англоязычного stackOverflow, быстрым взглядом на комментарий к четвертому аргументу "filter boolean: true if the source should be filtered." из которого я ничего не понял, решил не трогать и забыл про него, думал причина не в этом.

Bitmap.createScaledBitmap(bm, 1000, 1000, false);

Долгий гуглеж привел к этому ответу What does the filter parameter to createScaledBitmap do?

To expand on Karan's answer: As a general rule you won't see any difference if you're scaling your image down, but you will if you're scaling it up.

Passing filter = false will result in a blocky, pixellated image.

Passing filter = true will give you smoother edges.

However, as EIYeante pointed out in the comments, you might still see a difference. This is their example image.

Заменив false на true я получил удовлетворительный для меня результат. При значении false после масштабирования края фигур/линий были угловатые/коцаные/грубые. При значении true линии гладкие, результат намного лучше.

Bitmap.createScaledBitmap(bm, 1000, 1000, true);

READ ALSO
Как сохранить действие кнопки Button при смене ореинтации (а точнее сделать так что бы метод setAnswerShownResult) не “сбивался”

Как сохранить действие кнопки Button при смене ореинтации (а точнее сделать так что бы метод setAnswerShownResult) не “сбивался”

При повороте экрана активность останавливается и запускается снова, поэтому восстаналивается положение как после выполнения onCreate()Чтобы...

158
JavaFX некорректный вывод X-Bee пакета в файл

JavaFX некорректный вывод X-Bee пакета в файл

Имеется строковая переменная

179
Проблема при первом запуске Oracle SQL Developer

Проблема при первом запуске Oracle SQL Developer

Проблема точно такая же, как описана здесь - https://stackoverflowcom/questions/52484814/oracle-sql-developer-problem-initializing-welcome-page

205
Проблема в java конструкторe Java

Проблема в java конструкторe Java

Код компилируется но выдаёт ошибки(

185