4

I'm working on a website that allows users to upload images and crop them. I convert every image to .PNG for better quality. The problem I'm having is the picture size.

If I upload a 200 kb image, after cropping and making it PNG it has 600 kb. This is not a solution for me, because the images are stored in the database as BLOBs and the website loads slower.

I'm trying to find a way to compress the png, to have a smaller size, without reducing the quality.

I couldn't find any library or solution for this problem. I need something for Java like TinyPNG.

This is how I do it:

    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();

And this is the resizeImage function:

    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
    You can't improve the image quality by converting it to a PNG. – chrylis -cautiouslyoptimistic- Jul 30 '14 at 08:46
  • I tested. If I resize it to a smaller size (from 500x500 to 400x400) the quality reduces considerably. If I save the images as PNG the quality is ok. – Cristina Nicolae Jul 30 '14 at 08:48
  • possible duplicate of [how to compress a PNG image using Java](http://stackoverflow.com/questions/2721303/how-to-compress-a-png-image-using-java) – DavidPostill Jul 30 '14 at 08:51
  • Is there a reason you're sending this through a `Graphics2D` instead of using a dedicated image-manipulation tool/library like ImageMagick? – chrylis -cautiouslyoptimistic- Jul 30 '14 at 08:54
  • I used Graphics2D because this way I set RenderingHints for better quality. That's what I found on stackoverflow somewhere. I am pretty new in this field, sorry. I don't know the best solutions. – Cristina Nicolae Jul 30 '14 at 08:58
  • If the JPEG qualitity is low you have saved the JPEG file with a low image quality value. Increase the image quality and you get better results. See [How to set Jpeg quality](http://stackoverflow.com/questions/13204432/java-how-to-set-jpg-quality) – Robert Jul 30 '14 at 08:58

1 Answers1

0

On tinypng website they have explained in how doe it work question that how they compress the image see below:

How does it work?

Excellent question! When you upload a PNG (Portable Network Graphics) file, similar colors in your image are combined. This technique is called “quantization”. By reducing the number of colors, 24-bit PNG files can be converted to much smaller 8-bit indexed color images. All unnecessary metadata is stripped too. The result better PNG files with 100% support for transparency. Have your cake and eat it too!

Absolutely they are using some libraries for that,

You can use http://pngquant.org/ for compressing or reducing size of image,

In another SO question someone answered that tinypng also uses pngquant library, but i don't know how far the truth in it, but you can use this library in Java also,

In the pngquant website they have given the java library link, take a look at it, i have provided that same github repository link as provided in website:

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

Basically the above library is written in c/c++ so it uses JNI(Java Native Interface) the interface which joins c/c++ with Java.

Haritsinh Gohil
  • 5,818
  • 48
  • 50