Мне нужно изменить размер файлов PNG, JPEG и GIF. Как я могу это сделать с помощью Java?
Мне нужно изменить размер файлов PNG, JPEG и GIF. Как я могу это сделать с помощью Java?
Ответы:
После загрузки изображения вы можете попробовать:
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 пикселей в высоту, и по умолчанию он автоматически выберет для этого наиболее удобный и самый быстрый подход, поскольку он не был не уточняется.
Я понимаю, что вначале это похоже на саморекламу (так оно и есть), но я потратил немало времени на поиски в Google точно такой же темы и продолжал придумывать разные результаты / подходы / мысли / предложения и решил сесть и написать простая реализация, которая решила бы те 80-85% случаев использования, когда у вас есть изображение и, вероятно, вам нужна его миниатюра - как можно быстрее или как можно красивее (для тех, кто пробовал, вы заметите при выполнении Graphics.drawImage даже с интерполяцией BICUBIC для достаточно маленького изображения это все равно выглядит мусором).
new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()
. Мне твой способ тоже нравится, и я думаю, что он проще.
Thumbnailator - это библиотека для изменения размера изображений с открытым исходным кодом для Java с плавным интерфейсом, распространяемая по лицензии MIT.
Я написал эту библиотеку, потому что создание высококачественных эскизов на Java может быть на удивление трудным, а полученный код может быть довольно беспорядочным. С помощью Thumbnailator можно выражать довольно сложные задачи с помощью простого беглого API.
Простой пример
В качестве простого примера, взяв изображение и изменив его размер до 100 x 100 (с сохранением соотношения сторон исходного изображения), и сохранив его в файл, можно выполнить одно действие:
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
Продвинутый пример
Быстрый интерфейс Thumbnailator упрощает выполнение сложных задач по изменению размера.
Предположим, мы хотим сделать следующее:
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 Чет Хаасе и Роменом Гаем, для создания высококачественных эскизов при обеспечении приемлемой производительности во время выполнения.
Для этого вам не нужна библиотека. Вы можете сделать это с помощью самой Java.
У Криса Кэмпбелла есть отличное и подробное описание масштабирования изображений - см. Эту статью .
Чет Хаасе и Ромен Гай также опубликовали подробную и очень информативную статью о масштабировании изображений в своей книге Filthy Rich Clients .
Java Advanced Imaging теперь имеет открытый исходный код и обеспечивает необходимые вам операции.
Если вы имеете дело с большими изображениями или хотите получить красивый результат, в java это нетривиальная задача. Простое выполнение этого с помощью операции масштабирования через Graphics2D не приведет к созданию высококачественного эскиза. Вы можете сделать это с помощью JAI, но это требует больше работы, чем вы можете себе представить, чтобы получить что-то, что хорошо выглядит, и у JAI есть неприятная привычка выдувать нашу JVM ошибками OutOfMemory.
Я предлагаю использовать ImageMagick в качестве внешнего исполняемого файла, если вам это удастся. Он прост в использовании и выполняет свою работу правильно, так что вам не придется это делать.
Если у вас есть возможность установить imagemagick на вашем компьютере, я рекомендую im4java . Это очень тонкий слой абстракции в интерфейсе командной строки, но он очень хорошо выполняет свою работу.
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);
Вы можете попробовать использовать систему обработки изображений GraphicsMagick с im4java в качестве интерфейса строки для Java.
У GraphicsMagick много преимуществ, но одно на всех:
Была упомянута магия изображений. Существует интерфейсный проект JNI под названием JMagick. Это не особо стабильный проект (известно, что сама Image Magick сильно меняет и даже нарушает совместимость). Тем не менее, у нас есть хороший опыт использования JMagick и совместимой версии Image Magick в производственной среде для выполнения масштабирования с высокой пропускной способностью и низкой задержкой. Скорость была значительно выше, чем у графической библиотеки Java, которую мы пробовали ранее.
Просто используйте ответ Буркхарда, но добавьте эту строку после создания графики:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
Вы также можете установить значение BICUBIC, это даст изображение лучшего качества, но это более дорогая операция. Вы можете установить и другие подсказки рендеринга, но я обнаружил, что наиболее заметный эффект дает интерполяция. Имейте в виду, что если вы хотите сильно увеличить масштаб, код Java, скорее всего, будет очень медленным. Я обнаружил, что большие изображения начинают давать задержку около 300% масштабирования, даже если все подсказки рендеринга настроены на оптимизацию скорости по качеству.
Вы можете использовать Marvin (чистую среду обработки изображений Java) для такого рода операций: http://marvinproject.sourceforge.net
Плагин масштабирования: http://marvinproject.sourceforge.net/en/plugins/scale.html
Оказывается, написать эффективный скейлер нетривиально. Я сделал это однажды для проекта с открытым исходным кодом: ImageScaler. .
В принципе, java.awt.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;
}
}
Попробуйте следующий метод:
ImageIcon icon = new ImageIcon("image.png");
Image img = icon.getImage();
Image newImg = img.getScaledInstance(350, 350, java.evt.Image.SCALE_SMOOTH);
icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, "image on The frame", "Display Image", JOptionPane.INFORMATION_MESSAGE, icon);