Как изменить размер изображения с помощью Java?
Мне нужно изменить размер файлов PNG, JPEG и GIF. Как я могу сделать это с помощью Java?
16 ответов
после загрузки изображения вы можете попробовать:
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;
}
fwiw я только что выпустил (Apache 2, размещенный на GitHub) простую библиотеку масштабирования изображений для Java под названием imgscalr (доступный на Maven central).
библиотека реализует несколько различных подходов к масштабированию изображений (включая инкрементный подход Криса Кэмпбелла с несколькими незначительными улучшениями) и либо выберет наиболее оптимальный подход для вас, если вы попросите его, либо даст вам самый быстрый или самый красивый (если вы попросите что.)
использование мертво-просто, просто куча статических методов. Самый простой вариант использования:
BufferedImage scaledImage = Scalr.resize(myImage, 200);
все операции поддерживают исходные пропорции изображения, поэтому в этом случае вы просите imgscalr изменить размер изображения в пределах 200 пикселей в ширину и 200 пикселей в высоту, и по умолчанию он автоматически выберет самый красивый и быстрый подход для этого, так как он не был указан.
Я понимаю, что с самого начала это выглядит как самореклама (это это), но я потратил свою справедливую долю времени на поиск в гугле этой же самой темы и продолжал придумывать разные результаты/подходы/мысли/предложения и решил сесть и написать простую реализацию, которая будет решать, что 80-85% случаев использования, когда у вас есть изображение и, вероятно, хотите эскиз для него-либо как можно быстрее, либо как можно красивее (для тех, кто пробовал, вы заметите, что делаете графику.drawImage даже с БИКУБИЧЕСКОЙ интерполяцией на достаточно маленькое изображение, это все еще выглядит как мусор).
Thumbnailator - это библиотека изменения размера изображений с открытым исходным кодом для Java с плавным интерфейсом, распространяемая под лицензия MIT.
Я написал эту библиотеку, потому что создание высококачественных эскизов на Java может быть удивительно сложным, и полученный код может быть довольно грязным. С помощью Thumbnailator можно выражать довольно сложные задачи с помощью простого fluent API.
простой пример
для простой пример, взяв изображение и изменив его размер до 100 x 100 (сохраняя соотношение сторон исходного изображения), и сохранение его в файл может быть достигнуто в одном заявлении:
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
расширенный пример
выполнение сложных задач изменения размера упрощается с помощью интерфейса Fluent Thumbnailator.
предположим, мы хотим сделать следующее:
- возьмите изображения в каталоге и,
- изменить их размер до 100 x 100, с соотношением сторон исходного изображения,
- сохранить их все в JPEGs с настройками качества
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);
заметки о качестве изображения и скорости
эта библиотека также использует прогрессивная билинейное масштабирование метод выделен в Грязные Богатые Клиенты Chet Haase и Romain Guy для создания высококачественных эскизов при обеспечении приемлемой производительности во время выполнения.
для этого не нужна библиотека. Вы можете сделать это с самой Java.
Крис Кэмпбелл имеет отличную и подробную запись о масштабировании изображений-см. в этой статье.
Chet Haase и Romain Guy также имеют подробную и очень информативную запись масштабирования изображений в своей книге, Грязные Богатые Клиенты.
Java Advanced Imaging теперь с открытым исходным кодом и предоставляет необходимые операции.
Если вы имеете дело с большими изображениями или хотите красивый результат, это не тривиальная задача на java. Просто делая это с помощью масштабирования op через Graphics2D не создаст эскиз высокого качества. Вы можете сделать это с помощью JAI, но это требует больше работы, чем вы могли бы себе представить, чтобы получить что-то, что выглядит хорошо, и JAI имеет неприятную привычку взорвать наш ваш JVM с ошибками OutOfMemory.
Я предлагаю использовать ImageMagick в качестве внешнего исполняемого файла, если вам это сойдет с рук. Его просто использовать и он работает правильно, так что вам не придется.
Если, имея imagemagick установлен на вашем maschine является вариантом, я рекомендую im4java. Это очень тонкий слой абстракции на интерфейсе командной строки, но делает свою работу очень хорошо.
вы можете попробовать использовать Система Обработки Изображений GraphicsMagick С im4java как интерфейс comand-line для Java.
есть много преимуществ GraphicsMagick, но один для всех:
- GM используется для обработки миллиардов файлы на самой большой фотографии в мире сайты (например, Flickr и Etsy).
API Java не предоставляет стандартную функцию масштабирования для изображений и понижения качества изображения.
из-за этого я попытался использовать 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);
была упомянута магия изображений. Существует проект JNI front end под названием JMagick. Это не особенно стабильный проект (и сама магия изображений, как известно, сильно меняется и даже нарушает совместимость). Тем не менее, у нас был хороший опыт использования JMagick и совместимой версии Image Magick в производственной среде для масштабирования с высокой пропускной способностью и низкой задержкой. Скорость была значительно лучше, чем со всей графической библиотекой Java, которую мы ранее пытался.
вы можете использовать Marvin (pure Java Image processing framework) для такого рода операций: http://marvinproject.sourceforge.net
масштабный плагин: http://marvinproject.sourceforge.net/en/plugins/scale.html
оказывается, что написание performant scaler не является тривиальным. Я сделал это однажды для проекта с открытым исходным кодом: ImageScaler.
в принципе ' java.ОУ.Image#getScaledInstance (int, int, int)' сделал бы эту работу, но есть неприятная ошибка с этим - обратитесь к моей ссылке для получения подробной информации.
Я разработал решение со свободно доступными классами (AnimatedGifEncoder, GifDecoder и LWZEncoder), доступными для обработки GIF-анимации.
Вы можете загрузить jgifcode jar и запустить класс GifImageUtil.
Ссылка:http://www.jgifcode.com
вы можете использовать следующий популярный продукт:thumbnailator
Если вы не хотите, чтобы импортировать imgScalr как @Riyad Kalla ответ, выше которого я тестировал тоже работает нормально, вы можете сделать это взято из Питер Вальзер ответ @Peter Walser по другому вопросу, хотя:
/**
* 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;
}
}
просто используйте ответ Буркхарда, но добавьте эту строку после создания графики:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
вы также можете установить значение BICUBIC, это произведет лучшее качество изображения, но это более дорогая операция. Есть и другие подсказки рендеринга, которые вы можете установить, но я обнаружил, что интерполяция дает наиболее заметный эффект. Имейте в виду, если вы хотите увеличить массу, Java-код, скорее всего, будет очень медленным. Я нахожу, что большие изображения начинают производить отставание около 300% Зума даже с все подсказки рендеринга настроены на оптимизацию для скорости по качеству.