Reputation: 51
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!!
Upvotes: 4
Views: 4214
Reputation: 6272
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
.
Upvotes: 0