Подтвердить что ты не робот

Как вы создаете уменьшенное изображение из JPEG на Java?

Может кто-то помочь с некоторым кодом для создания миниатюры для JPEG в Java.

Я новичок в этом, поэтому поэтапное объяснение будет оценено.

4b9b3361

Ответ 1

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, содержащее изображение нормального размера.

Ответ 2

Как вы, возможно, обнаружили "легкий" и "хороший результат", это две разные вещи. Я включил оба эти требования в очень простое 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.

Ответ 3

Это простой способ создания эскиза 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();
    }

}

Ответ 4

JMagick библиотека (и реализация ImageMagick в Java) будет иметь то, что вам нужно.

Ответ 5

приведенный выше код Java (с помощью методов scale/getCompatibleImage) отлично подойдет для меня, но когда я развернулся на сервере, он перестал работать, потому что у сервера не было отображения, связанного с ним, - кто-нибудь еще с этой проблемой может исправить это, используя:   BufferedImage bi = новый BufferedImage (w, h, BufferedImage.TYPE_INT_RGB);

вместо BufferedImage bi = getCompatibleImage (w, h);

и удаление метода getCompatibleImage

(более поздняя заметка - оказалось, что это отлично работает для большинства изображений, но у меня есть куча отдела маркетинга моей компании, который представляет собой 32-битные изображения jpeg с глубиной цвета, а библиотека выдает исключение формата неподдерживаемого изображения для всех этих:( - imagemagick/jmagick начинают выглядеть более привлекательными)

Ответ 7

Я просмотрел блог, в соответствии с которым у вас есть следующие варианты -

  • Для простых файлов RGB используйте ImageScalr. ImageIO class используется для чтения файлов и ImageScalr для создания эскизов.
  • Для поддержки RGB + CYMK используйте API ImageIO и JAI (Java Advanced Imaging) для чтения файлов и ImageScalr для создания эскизов.
  • Если вы не знаете, какие форматы файлов, цветной режим, с которыми вы собираетесь иметь дело, самым безопасным вариантом является использование ImageMagick.

Вот ссылка, которая дает полный ответ с фрагментами кода.

Ответ 9

Существует много возможностей для обработки изображений, которые вы можете сделать всего несколькими строками. В приведенном ниже примере генерируются миниатюры в разных разрешениях (с учетом ширины как ссылки), используя 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");

Ответ 10

Простой способ создания эскиза без растягивания или библиотеки. Работает с прозрачностью в 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;
}

Ответ 11

У меня есть 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;

} 

Ответ 12

Я знаю, что это довольно старый пост. Я искал решение для создания эскиза, поэтому в конечном итоге с помощью этого

Thumbnails.of(originalImage).scale(0.25).asBufferedImage();

если вы используете для мобильных устройств, предложите установить масштаб на 0,45

Thumbnails.of(originalImage).scale(0.45).asBufferedImage();

https://github.com/coobird/thumbnailator

Это, безусловно, намного быстрее, используя Graphics2D, поскольку они протестировали обе опции.