Java的类似TinyPNG的库——压缩图像大小

4
我正在开发一个允许用户上传并裁剪图像的网站。我将每个图像转换为.PNG以获得更好的质量。但我遇到了图片大小的问题。
如果我上传一个200kb的图像,经过裁剪和转换成PNG后,它的大小达到了600kb。这对我来说并不是一个解决方案,因为这些图像作为BLOBs存储在数据库中,网站加载速度变慢。
我正在寻找一种压缩PNG而不会降低质量的方法来减小文件大小。
在这个问题上我没有找到任何库或解决方案。我需要类似TinyPNG能用于Java的东西。
以下是我的操作步骤:
    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; 
}

Help me!!


1
将图像转换为PNG格式并不能提高其质量。 - chrylis -cautiouslyoptimistic-
我进行了测试。如果我将其调整为较小的尺寸(从500x500到400x400),质量会大大降低。如果我将图像保存为PNG格式,则质量还可以。 - Cristina Nicolae
可能是如何使用Java压缩PNG图像的重复问题。 - DavidPostill
你为什么要通过Graphics2D发送这个内容,而不是使用专门的图像处理工具/库,比如ImageMagick? - chrylis -cautiouslyoptimistic-
我使用了Graphics2D,因为这样我可以设置RenderingHints以获得更好的质量。这是我在stackoverflow上找到的。我在这个领域还很新,抱歉,我不知道最好的解决方案。 - Cristina Nicolae
如果JPEG图像质量较低,则已使用较低的图像质量值保存了JPEG文件。提高图像质量可以获得更好的结果。请参见如何设置JPEG质量 - Robert
1个回答

0
tinypng 网站上,他们解释了如何压缩图像的问题,如下所示:
“怎么做?”
很好的问题!当您上传PNG(便携式网络图形)文件时,图像中的类似颜色会被合并。这种技术称为“量化”。通过减少颜色数量,24位PNG文件可以转换为更小的8位索引彩色图像。所有不必要的元数据也将被剥离。结果是更好的PNG文件,完全支持透明度。同时还能保留优秀的图像质量!
显然,他们正在使用一些库进行操作。
您可以使用 http://pngquant.org/ 来压缩或减小图像的大小。
在另一个 SO 问题中,有人回答说 tinypng 也使用 pngquant 库,但我不知道其中的真实情况。但您也可以在 Java 中使用这个库。
在pngquant网站上,他们提供了Java库的链接,请查看它,我已经提供了与网站提供的相同的Github存储库链接:

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

以上库基本上是用c/c++编写的,因此它使用了JNI(Java Native Interface),这个接口连接c/c++Java


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接