Библиотека, аналогичная TinyPNG для Java — сжимает размер изображения

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

Если я загружаю изображение размером 200 КБ, после обрезки и создания PNG оно имеет 600 КБ. Это не решение для меня, потому что изображения хранятся в базе данных как BLOB, и сайт загружается медленнее.

Я пытаюсь найти способ сжать png, чтобы иметь меньший размер, не снижая качество.

Я не смог найти никакой библиотеки или решения для этой проблемы. Мне нужно что-то для Java, например TinyPNG.

Вот как я это делаю:

    BufferedImage resizedImage = resizeImage(image,extension,width,height); 
    System.out.println("dimensiuni:" + resizedImage.getHeight()+ "x" + resizedImage.getWidth()); 
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write( resizedImage, "png", baos );
    baos.flush();
    byte[] imageInByte = baos.toByteArray();
    baos.close();

А это функция resizeImage:

    public BufferedImage resizeImage(BufferedImage image, String extension, int targetWidth, int targetHeight) {


    int type = (image.getTransparency() == Transparency.OPAQUE) ?
            BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

        BufferedImage ret = (BufferedImage)image;
        int w, h;

            w = image.getWidth();
            h = image.getHeight();


        do {
            if (w > targetWidth) {
                w /= 2;
                if (w < targetWidth) {
                    w = targetWidth;
                }
            }

            if ( h > targetHeight) {
                h /= 2;
                if (h < targetHeight) {
                    h = targetHeight;
                }
            }

            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setComposite(AlphaComposite.Src);
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_DEFAULT);
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);


            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();

            ret = tmp;

            tmp.flush();


        } while (w != targetWidth || h != targetHeight);

        return ret; 
}

Помоги мне!!


person Cristina Nicolae    schedule 30.07.2014    source источник
comment
Вы не можете улучшить качество изображения, преобразовав его в PNG.   -  person chrylis -cautiouslyoptimistic-    schedule 30.07.2014
comment
Я тестировал. Если я уменьшаю его размер (с 500x500 до 400x400), качество значительно снижается. Если я сохраняю изображения в формате PNG, качество в порядке.   -  person Cristina Nicolae    schedule 30.07.2014
comment
возможный дубликат как сжать изображение PNG с помощью Java   -  person DavidPostill    schedule 30.07.2014
comment
Есть ли причина, по которой вы отправляете это через Graphics2D вместо использования специального инструмента/библиотеки для обработки изображений, такого как ImageMagick?   -  person chrylis -cautiouslyoptimistic-    schedule 30.07.2014
comment
Я использовал Graphics2D, потому что таким образом я устанавливал RenderingHints для лучшего качества. Это то, что я нашел где-то на stackoverflow. Я довольно новичок в этой области, извините. Я не знаю лучших решений.   -  person Cristina Nicolae    schedule 30.07.2014
comment
Если качество JPEG низкое, вы сохранили файл JPEG с низким значением качества изображения. Повысьте качество изображения, и вы получите лучшие результаты. См. Как установить качество Jpeg.   -  person Robert    schedule 30.07.2014


Ответы (1)


На веб-сайте tinypng они объяснили, как это работает, вопрос о том, как они сжимают изображение, см. ниже:

Как это работает?

Отличный вопрос! Когда вы загружаете файл PNG (Portable Network Graphics), похожие цвета изображения объединяются. Этот метод называется "квантование". Уменьшая количество цветов, 24-битные PNG файлы можно преобразовывать в гораздо меньшие 8-битные индексированные цветные изображения. Все ненужные метаданные также удаляются. В результате получаются более качественные файлы PNG со 100% поддержкой прозрачности. Возьми свой торт и съешь его тоже!

Абсолютно для этого они используют некоторые библиотеки,

Вы можете использовать http://pngquant.org/ для сжатия или уменьшения размера изображения,

В другом вопросе SO кто-то ответил, что tinypng также использует библиотеку pngquant, но я не знаю, насколько это правда, но вы можете использовать эту библиотеку и в Java,

На веб-сайте pngquant они дали ссылку на библиотеку java, взгляните на нее, я предоставил ту же ссылку на репозиторий github, что и на веб-сайте:

https://github.com/ImageOptim/libimagequant/tree/master/org/pngquant

В основном указанная выше библиотека написана на c/c++, поэтому она использует интерфейс JNI (собственный интерфейс Java), который объединяет c/c++ с Java.

person Haritsinh Gohil    schedule 18.11.2019