Может кто-то помочь с некоторым кодом для создания миниатюры для JPEG в Java.
Я новичок в этом, поэтому поэтапное объяснение будет оценено.
Может кто-то помочь с некоторым кодом для создания миниатюры для JPEG в Java.
Я новичок в этом, поэтому поэтапное объяснение будет оценено.
Image img = ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH);
Это создаст эскиз размером 100x100 пикселей в качестве объекта изображения. Если вы хотите записать его обратно на диск, просто преобразуйте код в это:
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
img.createGraphics().drawImage(ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, Image.SCALE_SMOOTH),0,0,null);
ImageIO.write(img, "jpg", new File("test_thumb.jpg"));
Также, если вас беспокоит проблема скорости (описанный выше метод довольно медленный, если вы хотите масштабировать многие изображения), используйте эти методы и следующее объявление:
private BufferedImage scale(BufferedImage source,double ratio) {
int w = (int) (source.getWidth() * ratio);
int h = (int) (source.getHeight() * ratio);
BufferedImage bi = getCompatibleImage(w, h);
Graphics2D g2d = bi.createGraphics();
double xScale = (double) w / source.getWidth();
double yScale = (double) h / source.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale);
g2d.drawRenderedImage(source, at);
g2d.dispose();
return bi;
}
private BufferedImage getCompatibleImage(int w, int h) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
return image;
}
И затем вызовите:
BufferedImage scaled = scale(img,0.5);
где 0,5 - масштабное отношение, а img - BufferedImage, содержащее изображение нормального размера.
Как вы, возможно, обнаружили "легкий" и "хороший результат", это две разные вещи. Я включил оба эти требования в очень простое java-изображение для масштабирования библиотеки (лицензия Apache 2), которая просто делает все правильно для вас.
Пример кода для создания эскиза выглядит следующим образом:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 150);
Ваши пропорции изображения соблюдены, библиотека дает наилучшее представление о методе, который он должен использовать, в зависимости от количества изменений изображения из-за масштабирования (FASTEST, BALANCED или QUALITY), а наилучшие поддерживаемые типы изображений Java2D всегда используется для масштабирования, чтобы избежать проблемы с "черными" результатами или действительно ужасно выглядящими выходными данными (например, чрезмерно затухающими изображениями GIF).
Кроме того, если вы хотите заставить его выводить наилучшую миниатюру в Java, вызов API будет выглядеть так:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY,
150, 100, Scalr.OP_ANTIALIAS);
Библиотека не только использует рекомендованное Java2D инкрементное масштабирование, чтобы дать вам наилучший результат, но также применит дополнительный эффект сглаживания к миниатюре (ConvolveOp с очень точно настроенным ядром) для каждого из них, слегка смягчите переходы между значениями пикселей, чтобы сделать эскиз более однородным, а не острым или маком, как вы могли видеть, когда вы переходите от очень больших изображений до очень маленьких.
Вы можете прочитать все комментарии в библиотеке (сам код сильно документирован), чтобы увидеть все различные ошибки JDK, которые были обработаны или оптимизированы для повышения производительности или использования памяти. Я потратил много времени на настройку этой реализации и получил много хороших отзывов от людей, развертывающих ее в веб-приложениях и других проектах Java.
Это простой способ создания эскиза 100 X 100 без какого-либо растяжения или искажения изображения.
private void saveScaledImage(String filePath,String outputFile){
try {
BufferedImage sourceImage = ImageIO.read(new File(filePath));
int width = sourceImage.getWidth();
int height = sourceImage.getHeight();
if(width>height){
float extraSize= height-100;
float percentHight = (extraSize/height)*100;
float percentWidth = width - ((width/100)*percentHight);
BufferedImage img = new BufferedImage((int)percentWidth, 100, BufferedImage.TYPE_INT_RGB);
Image scaledImage = sourceImage.getScaledInstance((int)percentWidth, 100, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
img2 = img.getSubimage((int)((percentWidth-100)/2), 0, 100, 100);
ImageIO.write(img2, "jpg", new File(outputFile));
}else{
float extraSize= width-100;
float percentWidth = (extraSize/width)*100;
float percentHight = height - ((height/100)*percentWidth);
BufferedImage img = new BufferedImage(100, (int)percentHight, BufferedImage.TYPE_INT_RGB);
Image scaledImage = sourceImage.getScaledInstance(100,(int)percentHight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
img2 = img.getSubimage(0, (int)((percentHight-100)/2), 100, 100);
ImageIO.write(img2, "jpg", new File(outputFile));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
JMagick библиотека (и реализация ImageMagick в Java) будет иметь то, что вам нужно.
приведенный выше код Java (с помощью методов scale/getCompatibleImage) отлично подойдет для меня, но когда я развернулся на сервере, он перестал работать, потому что у сервера не было отображения, связанного с ним, - кто-нибудь еще с этой проблемой может исправить это, используя: BufferedImage bi = новый BufferedImage (w, h, BufferedImage.TYPE_INT_RGB);
вместо BufferedImage bi = getCompatibleImage (w, h);
и удаление метода getCompatibleImage
(более поздняя заметка - оказалось, что это отлично работает для большинства изображений, но у меня есть куча отдела маркетинга моей компании, который представляет собой 32-битные изображения jpeg с глубиной цвета, а библиотека выдает исключение формата неподдерживаемого изображения для всех этих:( - imagemagick/jmagick начинают выглядеть более привлекательными)
Я создал приложение под названием fotovault (sourceforge.net), которое может загружать изображения и создавать эскизы в java с помощью imagej apis.
Пожалуйста, прочитайте мой блог ниже
http://www.gingercart.com/Home/java-snippets/create-image-thumbnail-in-java-using-imagej-api
Я просмотрел блог, в соответствии с которым у вас есть следующие варианты -
Вот ссылка, которая дает полный ответ с фрагментами кода.
Я использовал Thumbnailator! Он решил мою проблему с двумя строками кода.
Существует много возможностей для обработки изображений, которые вы можете сделать всего несколькими строками. В приведенном ниже примере генерируются миниатюры в разных разрешениях (с учетом ширины как ссылки), используя Marvin Framework. Три эскиза были сгенерированы в 92 мс.
ввод:
выход:
import static marvin.MarvinPluginCollection.*;
MarvinImage image = MarvinImageIO.loadImage("./res/input.jpg");
MarvinImage scaledImage = new MarvinImage(1,1);
scale(image, scaledImage, 250);
MarvinImageIO.saveImage(scaledImage, "./res/output_x250.jpg");
scale(image, scaledImage, 150);
MarvinImageIO.saveImage(scaledImage, "./res/output_x150.jpg");
scale(image, scaledImage, 50);
MarvinImageIO.saveImage(scaledImage, "./res/output_x50.jpg");
Простой способ создания эскиза без растягивания или библиотеки. Работает с прозрачностью в pngs тоже.
public File createThumbnail(String imageUrl, String targetPath) {
final int imageSize = 100;
File thumbnail = new File(targetPath);
try {
thumbnail.getParentFile().mkdirs();
thumbnail.createNewFile();
BufferedImage sourceImage = ImageIO.read(new File(imageUrl));
float width = sourceImage.getWidth();
float height = sourceImage.getHeight();
BufferedImage img2;
if (width > height) {
float scaledWidth = (width / height) * (float) imageSize;
float scaledHeight = imageSize;
BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
int offset = (int) ((scaledWidth - scaledHeight) / 2f);
img2 = img.getSubimage(offset, 0, imageSize, imageSize);
}
else if (width < height) {
float scaledWidth = imageSize;
float scaledHeight = (height / width) * (float) imageSize;
BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
int offset = (int) ((scaledHeight - scaledWidth) / 2f);
img2 = img.getSubimage(0, offset, imageSize, imageSize);
}
else {
img2 = new BufferedImage(imageSize, imageSize, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance(imageSize, imageSize, Image.SCALE_SMOOTH);
img2.createGraphics().drawImage(scaledImage, 0, 0, null);
}
ImageIO.write(img2, "png", thumbnail);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return thumbnail;
}
У меня есть writtena использовать класс со статическими методами много лет назад, используя JAI. Java Advanced Imaging API - это самый надежный API на Java для обработки изображений. Это векторная интерполяция ближе всего к Photoshop в мире Java. Вот один из них:
public static ByteArrayOutputStream resize(InputStream inputStream , int IMG_WIDTH,
int IMG_HEIGHT) throws Exception {
BufferedImage originalImage = ImageIO.read(inputStream);
int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB
: originalImage.getType();
BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
type);
{
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
g.dispose();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(resizedImage, "png", bos);
return bos;
}
Я знаю, что это довольно старый пост. Я искал решение для создания эскиза, поэтому в конечном итоге с помощью этого
Thumbnails.of(originalImage).scale(0.25).asBufferedImage();
если вы используете для мобильных устройств, предложите установить масштаб на 0,45
Thumbnails.of(originalImage).scale(0.45).asBufferedImage();
https://github.com/coobird/thumbnailator
Это, безусловно, намного быстрее, используя Graphics2D, поскольку они протестировали обе опции.