1. Введение
В этом уроке мы узнаем, как изменить размер (масштабировать) изображение с помощью Java. Мы рассмотрим как основные библиотеки Java, так и сторонние библиотеки с открытым исходным кодом, которые предлагают функцию изменения размера изображения.
Важно отметить, что мы можем масштабировать изображения как вверх, так и вниз. В примерах кода в этом руководстве мы будем уменьшать размеры изображений, поскольку на практике это наиболее распространенный сценарий.
2. Измените размер изображения с помощью Core Java
Core Java предлагает следующие варианты изменения размера изображений:
- Изменение размера с помощью
java.awt.Graphics2D
- Изменение размера с помощью
Image#getScaledInstance
2.1. java.awt.Graphics2D
Graphics2D
— это основной класс для визуализации двумерных фигур, текста и изображений на платформе Java.
Начнем с изменения размера изображения с помощью Graphics2D
:
BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException {
BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = resizedImage.createGraphics();
graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
graphics2D.dispose();
return resizedImage;
}
Давайте посмотрим, как выглядит изображение до и после изменения размера:
Параметр BufferedImage.TYPE_INT_RGB
указывает цветовую модель изображения. Полный список доступных значений доступен в официальной документации Java BufferedImage
.
Graphics2D
принимает дополнительные параметры, называемые RenderingHints
. Мы используем RenderingHints
, чтобы влиять на различные аспекты обработки изображений и, что наиболее важно, на качество изображения и время обработки.
Мы можем добавить RenderingHint
, используя метод setRenderingHint
:
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
Полный список RenderingHints
можно найти в этом руководстве по Oracle .
2.2. Изображение.getScaledInstance()
Этот подход с использованием изображения
очень прост и позволяет получать изображения удовлетворительного качества:
BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException {
Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_DEFAULT);
BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
return outputImage;
}
Давайте посмотрим, что происходит с изображением чего-то вкусненького:
Мы также можем указать механизму масштабирования использовать один из доступных подходов, предоставив методу getScaledInstance()
флаг, указывающий тип алгоритма, который будет использоваться для наших нужд передискретизации изображения:
Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);
Все доступные флаги описаны в официальной документации Java Image .
3. Имгскалер
Imgcalr использует Graphic2D
в фоновом режиме. Он имеет простой API с несколькими различными методами изменения размера изображения. ** **
Imgcalr предоставляет нам либо самый красивый результат, либо самый быстрый результат, либо сбалансированный результат в зависимости от выбранного нами параметра масштабирования. Также доступны другие функции обработки изображений, например обрезка и поворот. Покажем, как это работает на простом примере.
Мы добавим следующую зависимость Maven:
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
</dependency>
Проверьте Maven Central на наличие последней версии.
Самый простой способ использования Imgscalr:
BufferedImage simpleResizeImage(BufferedImage originalImage, int targetWidth) throws Exception {
return Scalr.resize(originalImage, targetWidth);
}
Где originalImage
— это BufferedImage
, размер которого нужно изменить, а targetWidth
— ширина результирующего изображения. Этот подход сохранит исходные пропорции изображения и использует параметры по умолчанию — Method.AUTOMATIC
и Mode.AUTOMATIC
.
Как это сделать с изображением вкусных фруктов? Посмотрим:
Библиотека также поддерживает несколько параметров конфигурации и поддерживает прозрачность изображения в фоновом режиме.
Наиболее важными параметрами являются:
режим
— используется для определения режимов изменения размера, которые будет использовать алгоритм. Например, мы можем определить, хотим ли мы сохранить пропорции изображения (варианты:AUTOMATIC, FIT_EXACT, FIT_TO_HEIGHT и FIT_TO_WIDTH
) .method
— инструктирует процесс изменения размера, чтобы его внимание было сосредоточено на скорости, качестве или на том и другом. Возможные значения:АВТОМАТИЧЕСКИЙ, СБАЛАНСИРОВАННЫЙ, КАЧЕСТВЕННЫЙ, СКОРОСТЬ, УЛЬТРА_КАЧЕСТВЕННЫЙ.
Также можно определить дополнительные свойства изменения размера, которые предоставят нам регистрацию или предоставят библиотеке некоторые изменения цвета изображения (сделать его светлее, темнее, оттенки серого и т. д.).
Давайте воспользуемся полной параметризацией метода resize() :
BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception {
return Scalr.resize(originalImage, Scalr.Method.AUTOMATIC, Scalr.Mode.AUTOMATIC, targetWidth, targetHeight, Scalr.OP_ANTIALIAS);
}
И теперь мы получаем:
Imgcalr работает со всеми файлами, поддерживаемыми Java Image IO — JPG, BMP, JPEG, WBMP, PNG и GIF.
4. Миниатюрист
Thumbnailator — это библиотека для изменения размера изображений с открытым исходным кодом для Java, которая использует прогрессивное билинейное масштабирование. Он поддерживает JPG, BMP, JPEG, WBMP, PNG и GIF.
Мы включим его в наш проект, добавив следующую зависимость Maven в наш pom.xml
:
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.11</version>
</dependency>
Доступные версии зависимостей можно найти на Maven Central .
Он имеет очень простой API и позволяет нам устанавливать качество вывода в процентах:
BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Thumbnails.of(originalImage)
.size(targetWidth, targetHeight)
.outputFormat("JPEG")
.outputQuality(1)
.toOutputStream(outputStream);
byte[] data = outputStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
return ImageIO.read(inputStream);
}
Давайте посмотрим, как выглядит эта улыбающаяся фотография до и после изменения размера:
Он также имеет возможность пакетной обработки:
Thumbnails.of(new File("path/to/directory").listFiles())
.size(300, 300)
.outputFormat("JPEG")
.outputQuality(0.80)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
Как и Imgscalr, Thumblinator работает со всеми файлами, поддерживаемыми Java Image IO — JPG, BMP, JPEG, WBMP, PNG и GIF.
5. Марвин
Marvin — это удобный инструмент для обработки изображений, который предлагает множество полезных базовых (обрезка, поворот, наклон, отражение, масштабирование) и расширенных (размытие, тиснение, текстурирование) функций.
Как и раньше, мы добавим зависимости Maven, необходимые для изменения размера Marvin:
<dependency>
<groupId>com.github.downgoon</groupId>
<artifactId>marvin</artifactId>
<version>1.5.5</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.github.downgoon</groupId>
<artifactId>MarvinPlugins</artifactId>
<version>1.5.5</version>
</dependency>
Доступные версии зависимостей Marvin можно найти на Maven Central вместе с версиями плагинов Marvin .
Недостатком Marvin является то, что он не предлагает дополнительную конфигурацию масштабирования. Кроме того, для метода масштабирования требуется изображение и клон изображения, что немного громоздко:
BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
MarvinImage image = new MarvinImage(originalImage);
Scale scale = new Scale();
scale.load();
scale.setAttribute("newWidth", targetWidth);
scale.setAttribute("newHeight", targetHeight);
scale.process(image.clone(), image, null, null, false);
return image.getBufferedImageNoAlpha();
}
Давайте теперь изменим размер изображения цветка и посмотрим, что получится:
6. Передовая практика
Обработка изображений — это дорогостоящая операция с точки зрения ресурсов, поэтому выбор самого высокого качества — не обязательно лучший вариант, когда он нам действительно не нужен.
Посмотрим на эффективность всех подходов. Мы взяли одно изображение размером 1920×1920 пикселей
и масштабировали его до 200×200 пикселей.
В результате наблюдаемое время выглядит следующим образом:
java.awt.Graphics2D
— 34 мсImage.getScaledInstance()
— 235 мс- Imgscalr — 143 мс
- Миниатюрист – 547 мс
- Марвин – 361 мс
Кроме того, при определении ширины и высоты целевого изображения следует обратить внимание на соотношение сторон изображения. Таким образом, изображение сохранит свои первоначальные пропорции и не будет растягиваться.
7. Заключение
В этой статье показано несколько способов изменения размера изображения в Java. Мы также узнали, сколько различных факторов может повлиять на процесс изменения размера.
Полные примеры кода доступны на GitHub .