Как изменить размер изображения с помощью Java?
Мне нужно изменить размер PNG, JPEG и GIF файлов. Как это сделать с помощью 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, которую мы ранее пробовали.
http://www.jmagick.org/index.html
Ответ 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;
}
}