Мне нужно изменить размер PNG, JPEG и GIF файлов. Как это сделать с помощью Java?
Как изменить размер изображения с помощью Java?
Ответ 1
После загрузки изображения вы можете попробовать:
BufferedImage createResizedCopy(Image originalImage,
int scaledWidth, int scaledHeight,
boolean preserveAlpha)
{
System.out.println("resizing...");
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
Ответ 2
FWIW Я только что выпустил (Apache 2, размещенный на GitHub) простую библиотеку масштабирования изображений для Java под названием imgscalr (доступно на центр Maven).
В библиотеке реализованы несколько разных подходов к масштабированию изображений (включая инкрементный подход Криса Кэмпбелла с несколькими незначительными усовершенствованиями) и либо выберете наиболее оптимальный для вас подход, если вы попросите его, либо предоставите вам самый быстрый или лучший вид (если вы просите об этом).
Использование мертво-простое, просто куча статических методов. Самый простой вариант использования:
BufferedImage scaledImage = Scalr.resize(myImage, 200);
Все операции поддерживают исходные пропорции изображения, поэтому в этом случае вы запрашиваете imgscalr для изменения размера изображения в пределах 200 пикселей в ширину и 200 пикселей в высоту, и по умолчанию он автоматически выбирает наилучший и самый быстрый способ для этого поскольку он не был указан.
Я понимаю, с самого начала это выглядит как самореклама (это так), но я потратил свою долю времени на поиски этого одного и того же предмета и продолжал придумывать разные результаты/подходы/мысли/предложения и решил сесть и напишите простую реализацию, которая адресовала бы 80-85% случаев использования, где у вас есть изображение, и, возможно, для него требуется миниатюра - как можно быстрее или как можно более красиво (для тех, кто попробовал, вы 'll замечает, что делает Graphics.drawImage даже с интерполяцией BICUBIC на достаточно маленьком изображении, он по-прежнему выглядит как мусор).
Ответ 3
Thumbnailator - это библиотека изменения размера изображения с открытым исходным кодом для Java с плавным интерфейсом, распространяемая по лицензии MIT.
Я написал эту библиотеку, потому что создание высококачественных миниатюр в Java может быть удивительно сложным, и полученный код может быть довольно грязным. С помощью Thumbnailator можно выразить довольно сложные задачи с помощью простого свободного API.
Простой пример
Для простого примера, взяв изображение и изменив его размер до 100 x 100 (сохраняя соотношение сторон исходного изображения) и сохраните его в файл, можно получить в одном выражении:
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
Расширенный пример
Выполнение сложных задач масштабирования упрощается с помощью свободного интерфейса Thumbnailator.
Предположим, что мы хотим сделать следующее:
- возьмите изображения в каталоге и
- измените размер до 100 x 100 с соотношением сторон исходного изображения,
- сохраните их все в формате JPEG с настройками качества
0.85
, - где имена файлов берутся из оригинала с
thumbnail.
, добавленным в начало
Переведенный на Thumbnailator, мы сможем выполнить вышеуказанное:
Thumbnails.of(new File("path/to/directory").listFiles())
.size(100, 100)
.outputFormat("JPEG")
.outputQuality(0.85)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
Заметка о качестве и скорости изображения
Эта библиотека также использует прогрессивный метод билинейного масштабирования, выделенный в Filthy Rich Clients Чет Хаазе и Роменом Гаем, чтобы генерировать высококачественные эскизы, обеспечивая при этом приемлемую производительность во время выполнения.
Ответ 4
Вам не нужна библиотека, чтобы сделать это. Вы можете сделать это с самой Java.
У Криса Кэмпбелла отличная и подробная информация о масштабировании изображений - см. эту статью.
Чет Хаас и Ромен Гай также подробно и очень информативно описывают масштабирование изображений в своей книге Filthy Rich Clients.
Ответ 5
Java Advanced Imaging теперь является открытым исходным кодом и предоставляет необходимые вам операции.
Ответ 6
Если вы имеете дело с большими изображениями или хотите получить красивый результат, это не тривиальная задача в java. Просто сделать это с помощью функции rescale op через Graphics2D не создаст миниатюру высокого качества. Вы можете сделать это с помощью JAI, но это требует больше работы, чем вы могли бы представить, чтобы получить что-то хорошее, и у JAI есть неприятная привычка выдувать нашу JVM с ошибками OutOfMemory.
Я предлагаю использовать ImageMagick в качестве внешнего исполняемого файла, если вы можете с ним справиться. Его прост в использовании, и он делает работу правильно, так что вам не нужно.
Ответ 7
Если у вас есть функция imagemagick, установленная на вашем компьютере, я рекомендую im4java. Это очень тонкий слой абстракции на интерфейсе командной строки, но делает его работу очень хорошо.
Ответ 8
Java API не предоставляет стандартную функцию масштабирования для изображений и снижения качества изображения.
Из-за этого я попытался использовать cvResize из JavaCV, но, похоже, это вызывает проблемы.
Я нашел хорошую библиотеку для масштабирования изображения: просто добавьте зависимость для "java-image-scaling" в ваш pom.xml.
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>java-image-scaling</artifactId>
<version>0.8.6</version>
</dependency>
В репозитории Maven вы получите последнюю версию для этого.
Ex. В вашей Java-программе
ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
Ответ 9
Вы можете попытаться использовать GraphicsMagick Image Processing System с im4java в качестве интерфейса comand-line для Java.
Существует много преимуществ GraphicsMagick, но один для всех:
- GM используется для обработки миллиардов файлов на крупнейшей в мире фотографии сайтов (например, Flickr и Etsy).
Ответ 10
Изображение Магия упоминается. Существует проект JNI front end под названием JMagick. Это не очень стабильный проект (и сам Image Magick, как известно, сильно меняет и даже нарушает совместимость). Тем не менее, у нас был хороший опыт использования JMagick и совместимой версии Image Magick в производственной среде для масштабирования с высокой пропускной способностью и низкой задержкой. Скорость была значительно лучше, чем со всей графической библиотекой Java, которую мы ранее пробовали.
Ответ 11
Вы можете использовать Marvin (чистая инфраструктура обработки изображений Java) для такого рода операций: http://marvinproject.sourceforge.net
Масштабный плагин: http://marvinproject.sourceforge.net/en/plugins/scale.html
Ответ 12
Просто используйте ответ Буркхарда, но добавьте эту строку после создания графики:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
Вы также можете установить значение BICUBIC, оно будет производить изображение более высокого качества, но это более дорогостоящая операция. Есть другие подсказки для рендеринга, которые вы можете установить, но я обнаружил, что интерполяция производит наиболее заметный эффект. Имейте в виду, если вы хотите увеличить масштаб, java-код, скорее всего, будет очень медленным. Я нахожу, что большие изображения начинают создавать отставание около 300% зум даже при всех подсказках, настроенных для оптимизации скорости по качеству.
Ответ 13
Оказывается, написание полноценного скалера не тривиально. Я сделал это один раз для проекта с открытым исходным кодом: ImageScaler.
В принципе, 'java.awt.Image # getScaledInstance (int, int, int)' также справился бы с этой задачей, но с этим связана одна неприятная ошибка - подробности см. В моей ссылке.
Ответ 14
Я разработал решение со свободно доступными классами (AnimatedGifEncoder, GifDecoder и LWZEncoder), доступными для обработки анимации GIF.
Вы можете загрузить jgifcode jar и запустить класс GifImageUtil.
Ссылка: http://www.jgifcode.com
Ответ 15
вы можете использовать следующий популярный продукт: thumbnailator
Ответ 16
Если вы не хотите импортировать imgScalr, как @Riyad Kalla ответ выше, который я тестировал тоже отлично работает, вы можете сделать это взято из Питер Уолсер ответил @Питер Валсер по другому вопросу:
/**
* utility method to get an icon from the resources of this class
* @param name the name of the icon
* @return the icon, or null if the icon wasn't found.
*/
public Icon getIcon(String name) {
Icon icon = null;
URL url = null;
ImageIcon imgicon = null;
BufferedImage scaledImage = null;
try {
url = getClass().getResource(name);
icon = new ImageIcon(url);
if (icon == null) {
System.out.println("Couldn't find " + url);
}
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.dispose();
bi = resizeImage(bi,30,30);
scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
imgicon = new ImageIcon(scaledImage);
} catch (Exception e) {
System.out.println("Couldn't find " + getClass().getName() + "/" + name);
e.printStackTrace();
}
return imgicon;
}
public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
float scaleX = (float) areaWidth / image.getWidth();
float scaleY = (float) areaHeight / image.getHeight();
float scale = Math.min(scaleX, scaleY);
int w = Math.round(image.getWidth() * scale);
int h = Math.round(image.getHeight() * scale);
int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
boolean scaleDown = scale < 1;
if (scaleDown) {
// multi-pass bilinear div 2
int currentW = image.getWidth();
int currentH = image.getHeight();
BufferedImage resized = image;
while (currentW > w || currentH > h) {
currentW = Math.max(w, currentW / 2);
currentH = Math.max(h, currentH / 2);
BufferedImage temp = new BufferedImage(currentW, currentH, type);
Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized, 0, 0, currentW, currentH, null);
g2.dispose();
resized = temp;
}
return resized;
} else {
Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;
BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image, 0, 0, w, h, null);
g2.dispose();
return resized;
}
}