Improving jpeg image quality using scaling in java - java

I am generating a jpg image using phantomjs. I want image with 600x400px dimension and 144 dpi/ppi.
But I am only able to generate a image with 72dpi. So, I am trying to generate the image with 1200x800px dimensions in 72 dpi and then resizing it to 600x400px.
so my idea is,
1200x800 px has dpi 72
so,
600x400px will have dpi 72*2 = 144 (because 1200/2=600px , 800/2=400px )
I am using java. But whenever I resize my image the quality becomes less.
Approaches I tried :
I tried to manipulate the metadata information of image as explained in the post below, but still it gives image with poor quality.
Increasing Resolution and Reducing Size of an Image in Java
Write dpi metadata to a jpeg image in Java
I tried using AffineTransform as given in following post, still not satisfied with results:
Java image scaling improve quality?
Am I using a wrong approach? If yes, then please suggest some alternatives.
If the approach is right then please guide me on how to implement it correctly?
UPDATE
I don't want to reduce the no. of pixels. I want to keep the no. of pixels same but reduce the height/width of image while increasing the dpi.
example, In an image of 1200x800px having 72 dpi, I will reduce it to 600x400 px while increasing dpi to 144 .
So , if you see the no of pixels are same and the image has higher dpi value.
Finally solved it using itext renderer. Refer to the following post on
using itext for scaling the large image to increase resolution.
Image Quality using Itext

I solved it using Itext.
File file = new File("demo.png");
Image img = Image.getInstance(file.getName());
img.scaleAbsolute(width, height); //where width,height is the reduced width,height; in my case 600,400.
Read it through Image class and use scaleAbsolute().
For more details please read this post:
Image Quality using Itext
PS: This is only helpful if you are trying to put image in pdf.
If anyone knows how to convert img to a png file then please comment.

Related

Should I convert BufferedImage.TYPE_4BYTE_ABGR to BufferedImage.TYPE_3BYTE_BGR?

I am working on image interpolation for which I am using bi-cubic interpolation to double the resolution of image in java using AffinedTransformOp.I used BufferedImage of TYPE_4BYTE_ABGR while doing up-scaling. When I tried to save back my upscale image using ImageIO.write then I found that openjdk does not support jpeg encoding for TYPE_4BYTE_ABGR so I converted this up-scaled image from TYPE_4BYTE_ABGR to TYPE_3BYTE_BGR. When I saved it in folder then found that the memory taken by this upscale image is way less(about half time) than the memory taken by original image.
So I assume that the original(input) image is represented by four channels ARGB while upscale(output) image is taking 3 channels RGB and that's why getting less memory.
Now my question is that should I use this conversion?
Is there some information that is getting lost?
Does quality of image remains same?
P.S: I've read from the documentation of ImageIO that when we convert ARGB to RGB than the alpha value gets premultiplied to RGB values and I think it should not affect the quality of the image.
I solved my problem and hope to share my answer. Actually the type of my original image was Grayscale and the color space of my original image was grey (meaning only one channel with 8 bits) with quality of 90.Problem arised when I used TYPE_4BYTE_ABGR for the upscaling instead of using TYPE_BYTE_GRAY. Secondly when you try to save this image in a file in jpeg format ImageIO.write uses compression of 75 by default so the image size will get small. You should use the compression factor which suits you or you should save it in PNG format. You can view information about your image by using identify -verbos image.jpg in linux and can see the color space, image type and quality etcYou can check this post to see how to set your compression quality manually in ImageIO.

Image getting printed with low resolution

I have a requirement to create pdf with images for printing. I am adding a high resolution image to pdf using iText. It's reducing the quality to 72 DPI.
Resulting in poor quality of image after printing.
The original image resolution is 2549*3304 and DPI (300).
I tried below options
image.scaleAbsolute(2549*.24 ,3304*.24 );
image.setDpi(300,300);
image.scaleToFit(2549*.24 ,3304*.24 );
current code looks like this
Document document = new Document(PageSize.LETTER);
document.open();
Image image = Image.getInstance("C:/Project/bg.png");
image.setAbsolutePosition(0,0);
image.scalePercent(24);
document.add(image);
document.close();
I went through some threads (Adding an image to a PDF using iTextSharp and scale it properly) still not able to solve the problem
Can anyone please help me on this to get better image quality while printing?
The setDpi() method is irrelevant in your code, so is the DPI of your original image. Pixels are treated as points in iText. This means that adding an image as-is will result in having 72 pixels per inch.
You scale the image to 24 percent of the original size. This means that you increase the resolution: you are showing the same number of pixels using only 24% of the space. In this case, you are showing 2549 pixels distributed over 611.76 points. This is about 8.5 inch, which means you indeed have a resolution of 300 DPI.
I think the problem isn't caused by the resolution of the image inside the PDF (but it's hard to tell because we can't inspect the PDF). I think the problem is caused by the printing process that prints the document using a resolution that is different from the resolution in the PDF.
In any case: iText does not reduce the number of pixels if you use the methods scalePercent(), scaleAbsolute() or scaleToFit().
Extra info based on Comments:
Asking a PDF for its "resolution" doesn't make sense, because a PDF doesn't have any resolution (although images inside a PDF may have one). I have no idea why Photoshop tells you the resolution is 72 DPI. Maybe that's a default value because the measurment unit in PDF corresponds with a point and there are 72 points in one inch.
I have examined the PDF that you shared. I don't see any loss of resolution when I look at it on my screen. I can see that the document measures 8.5 by 11 inch. As for the image, please take a look at the report generated by Acrobat:
It says width/height: 2550/3300 in pixel.
2550 / 8.5 = 300
3300 / 11 = 300
Hence the resolution is 300 pixels per inch. Or: the PDF is created exactly the way you want it.
However: you say that the resolution is worse when you print the document. This can be caused by many different things: maybe you're printing on a page that is larger than 8.5 by 11 inch, maybe the printer can't print at that resolution, maybe the PDF viewer can only print using "degraded printing",...
My advice is that you test this PDF on different printers using different viewers to find the culprit.

Zoom out an image with java

I have a program whereby the user will enter the url for a picture, then a program in java should zoom out the picture with a width and height which are both multiple of 135px.
Can someone help??
for e.g. this is an image 1100X1121
but i want width and the height of the image to become both multiple of 135 and less than 700px as below, now the image is 675X675 which is both a multiple of 135px and less than 700px:
I am using java-image-scaling-library for scaling and it works fine. It makes it easier to determine the width and/or height of the new image.
(Note that it is most often called "scaling")
You can try this simple Java library: Imgscalr
Or is your problem to determine the dimensions of new image?

Java Image Writing

I want to create thousands of dynamic images with Java. I've created a JFrame and a LayeredPane and put a JLabel on this. Then I am writing image contents in this JLabel. Then I create this image of this LayeredPane like this
BufferedImage image = (BufferedImage)comp.createImage(width, hight);
It creates the image perfectly but its size is 20KB (more or less). Can I reduce the image size without losing its quality. I have just text and colour in JLabel.
OR
Is there another way to create images based on Text?
Thanks in Advance
You can reduce its size on disk by saving as JPEG and reducing the Q. This has least impact on quality. Resampling has major impact.
For Text-only images containing only a little number of colors, storing them as GIF files (with a palette of only 2 or 3 colors) could be a lot smaller that JPEG, which is optimized for storing full-color pictures. I would start fiddling around with Paint.NET or some other tool to find out what's possible and which format is the best, before programming the Image-to-file-encoding.

Full Resolution Camera Access in j2me

I'm trying to do an image capture on a high end Nokia phone (N95). The phone's internal camera is very good (4 megapixels) but in j2me I only seem to be able to get a maximum of 1360x1020 image out. I drew largely from this example http://developers.sun.com/mobility/midp/articles/picture/
What I did was start with 640x480 and increase the width and height by 80 and 60, respectively until it failed. The line of code is:
jpg = mVideoControl.getSnapshot("encoding=jpeg&quality=100&width=" + width + "&height=" + height);
So the two issues are:
1. The phone throws an exception when getting an image larger than 1360x1020.
2. The higher resolution images appear to be just smoothed versions of the smaller ones. E.g. When I take a 640x480 image and increase it in photoshop I can't tell the difference between this and one that's supposedly 1360x1020.
Is this a limitation of j2me on the phone? If so does anyone know of a way to get a higher resolution from within a j2me application and/or how to access the native camera from within another application?
This explanation on Nokia forum may help you.
It says that "The maximum image size that can be captured depends on selected image format, encoding options and free heap memory available."
and
"It is thus strongly adviced that at least larger images (larger than 1mpix) are captured as JPEG images and in a common image size (e.g. 1600x1200 for 2mpix an so on). Supported common image sizes are dependent on product and platform version."
So I suggest you to take some tries
1. with 1600x1200, 1024x768 and whatever image resolution your N95 guide mentions
2. with BMP and PNG as well.
Anyway, based on my earlier experiences (that could be outdated), j2me implementations are full of bugs, so there may not be a working solution to your problem.
Your cameras resolution is natively:
2582 x 1944 . Try capturing there to see how that goes.
This place:
http://developers.sun.com/mobility/midp/articles/picture/index.html
Mentions the use of:
byte[] raw = mVideoControl.getSnapshot(null);
Image image = Image.createImage(raw, 0, raw.length);
The use of raw seems interesting, to get the native resolution.
The 'quality' of a JPEG (As interpreted by the code) is nothing to do with the resolution. Rather it is to do with how compressed the image is. A 640x480 image at 100 quality will be noticably better looking than a 640x480 image at 50, but will use more storage space.
Try this instead:
jpg = mVideoControl.getSnapshot("encoding=jpeg&quality=100&width=2048&height=1536");

Categories