Как изменить размер изображения с помощью 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 х 100 (сохраняя соотношение сторон исходного изображения), и сохранение его в файл можно добиться в одном заявлении:
Thumbnails.of("path/to/image") .size(100, 100) .toFile("path/to/thumbnail");
расширенный пример
выполнение сложных задач изменения размера упрощается с помощью интерфейса fluent Thumbnailator.
предположим, что мы хотим сделать следующее:
- возьмите изображения в каталог и,
- изменить их размер 100 х 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);
заметки о качестве изображения и скорости
эта библиотека также использует прогрессивная билинейное масштабирование метод выделен в Грязные Богатые Клиенты чет Хаасе и Ромен Гай для создания высококачественных эскизов, обеспечивая при этом приемлемую производительность во время выполнения.
вам не нужна библиотека, чтобы сделать это. Вы можете сделать это с самой Java.
Крис Кэмпбелл имеет отличную и подробную запись о масштабировании изображений-см. в этой статье.
Chet Haase и Romain Guy также имеют подробную и очень информативную запись масштабирования изображений в своей книге, Грязные Богатые Клиенты.
Java Advanced Imaging теперь с открытым исходным кодом и предоставляет необходимые операции.
Если вы имеете дело с большими изображениями, или хотите хороший результат это не тривиальная задача в Java. Просто делая это с помощью масштабирования op через Graphics2D не будет создавать эскиз высокого качества. Вы можете сделать это с помощью JAI, но это требует больше работы, чем вы могли бы себе представить, чтобы получить что-то, что выглядит хорошо, и JAI имеет неприятную привычку дуть наш ваш JVM с ошибками OutOfMemory.
Я предлагаю использовать ImageMagick в качестве внешнего исполняемого файла, если вы можете уйти с ним. Его просто, чтобы использовать и он работает правильно, так что вам не придется.
Если, имея imagemagick установлен на вашем maschine является опцией, я рекомендую im4java. Это очень тонкий слой абстракции на интерфейсе командной строки, но делает свою работу очень хорошо.
вы можете попробовать использовать GraphicsMagick Система Обработки Изображений С im4java как командный интерфейс для 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. Это не особенно стабильный проект (и сама Image Magick, как известно, сильно меняется и даже нарушает совместимость). Тем не менее, у нас был хороший опыт использования 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.ОУ.Изображение#getScaledInstance (int, int, int)' также выполнит эту работу, но есть неприятная ошибка с этим - см. мою ссылку для получения подробной информации.
Я разработал решение с свободно доступными классами (AnimatedGifEncoder, GifDecoder и LWZEncoder), доступными для обработки GIF-анимации.
Вы можете скачать jgifcode jar и запустить класс GifImageUtil. Ссылка:http://www.jgifcode.com
вы можете использовать следующий популярный продукт: thumbnailator
Если вы не хотите, чтобы импортировать 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; } }
просто используйте ответ Буркхарда, но добавьте эту строку после создания графики:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
вы также можете установить значение BICUBIC, он будет производить изображение лучшего качества, но это более дорогая операция. Есть и другие подсказки рендеринга, которые вы можете установить, но я обнаружил, что интерполяция производит наиболее заметный эффект. Имейте в виду, что если вы хотите увеличить масштаб, java-код, скорее всего, будет очень медленным. Я нахожу, что большие изображения начинают производить задержку около 300% Зума даже с все подсказки рендеринга настроены на оптимизацию для скорости над качеством.