Перейти к основному содержимому

Как я могу изменить размер изображения с помощью Java?

· 6 мин. чтения

1. Введение

В этом уроке мы узнаем, как изменить размер (масштабировать) изображение с помощью Java. Мы рассмотрим как основные библиотеки Java, так и сторонние библиотеки с открытым исходным кодом, которые предлагают функцию изменения размера изображения.

Важно отметить, что мы можем масштабировать изображения как вверх, так и вниз. В примерах кода в этом руководстве мы будем уменьшать размеры изображений, поскольку на практике это наиболее распространенный сценарий.

2. Измените размер изображения с помощью Core Java

Core Java предлагает следующие варианты изменения размера изображений:

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;
}

Давайте посмотрим, как выглядит изображение до и после изменения размера:

./a34c0f40944c9bd6d623a2a7aa758da0.jpg

./ea9b2fdbaaae3ebea1ff7bf4198cf7a5.jpg

Параметр 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;
}

Давайте посмотрим, что происходит с изображением чего-то вкусненького:

./bd61cdf94ade0b71ceb292496271c0b6.jpg

./555b02958b84a08418b1ae2bba758d44.jpg

Мы также можем указать механизму масштабирования использовать один из доступных подходов, предоставив методу 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 .

Как это сделать с изображением вкусных фруктов? Посмотрим:

./153cd9d081104a9bd949e22aadaaf2a1.jpg

./573467b4fe2a8b2ccb6409f88dd8b33d.jpg

Библиотека также поддерживает несколько параметров конфигурации и поддерживает прозрачность изображения в фоновом режиме.

Наиболее важными параметрами являются:

  • режим — используется для определения режимов изменения размера, которые будет использовать алгоритм. Например, мы можем определить, хотим ли мы сохранить пропорции изображения (варианты: 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);
}

И теперь мы получаем:

./153cd9d081104a9bd949e22aadaaf2a1.jpg

./75dbe7eedfe494b9a4b08b321ed130da.jpg

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);
}

Давайте посмотрим, как выглядит эта улыбающаяся фотография до и после изменения размера:

./999f72c86238d778c25c90bb7781c4fe.jpg

./2eb95e0925511ffeff120533f413c6f1.jpg

Он также имеет возможность пакетной обработки:

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();
}

Давайте теперь изменим размер изображения цветка и посмотрим, что получится:

./21e68ffc916afae17e91630e3bbefd1a.jpg

./66828fbf80acac0a38e73e1677e5aed8.jpg

6. Передовая практика

Обработка изображений — это дорогостоящая операция с точки зрения ресурсов, поэтому выбор самого высокого качества — не обязательно лучший вариант, когда он нам действительно не нужен.

Посмотрим на эффективность всех подходов. Мы взяли одно изображение размером 1920×1920 пикселей и масштабировали его до 200×200 пикселей. В результате наблюдаемое время выглядит следующим образом:

  • java.awt.Graphics2D — 34 мс
  • Image.getScaledInstance() — 235 мс
  • Imgscalr — 143 мс
  • Миниатюрист – 547 мс
  • Марвин – 361 мс

Кроме того, при определении ширины и высоты целевого изображения следует обратить внимание на соотношение сторон изображения. Таким образом, изображение сохранит свои первоначальные пропорции и не будет растягиваться.

7. Заключение

В этой статье показано несколько способов изменения размера изображения в Java. Мы также узнали, сколько различных факторов может повлиять на процесс изменения размера.

Полные примеры кода доступны на GitHub .