kerzner
asked on
Quality of reduced images
Hi,
I am loading TIF images, and showing them reduced in my app. The quality really suffers. I am displaying original text images, and even at small reduction I can not read them anymore.
On the other hand, when MS Paint reduces images, they are still readable.
I am using Jimi to load image (which shoud not matter), and Graphics.drawImage to display it.
Should I look at image processing techniques, the word dithering comes to mind, or should it be anything else?
Thank you.
I am loading TIF images, and showing them reduced in my app. The quality really suffers. I am displaying original text images, and even at small reduction I can not read them anymore.
On the other hand, when MS Paint reduces images, they are still readable.
I am using Jimi to load image (which shoud not matter), and Graphics.drawImage to display it.
Should I look at image processing techniques, the word dithering comes to mind, or should it be anything else?
Thank you.
Is the exact image is same size as the displayed one.
I don't know Jimi but you will probably find there are parameters you can pass to such a transformation, say about interpolation techniques and that sort of thing, that may offer some control over the quality of the outcome
ASKER
That is probably what I am looking for, something like this advice
http://mail.python.org/pipermail/image-sig/2002-March/001762.html
but for my answer I need a real instruction, more than general pointer
http://mail.python.org/pipermail/image-sig/2002-March/001762.html
but for my answer I need a real instruction, more than general pointer
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you, that looks very enticing, but produced blank images in my app. Could you please give more exlanation?
Here is how I used your code in my app
double ratio = 1;
AffineTransform scale = AffineTransform.getScaleIn stance(rat io, ratio);
BufferedImage scaled = new BufferedImage(r.width, r.height, BufferedImage.TYPE_INT_RGB );
Graphics2D g2 = scaled.createGraphics();
g2.setTransform(scale);
g2.drawImage(image, r.x, r.y, r.width, r.height, this);
Thank you.
Here is how I used your code in my app
double ratio = 1;
AffineTransform scale = AffineTransform.getScaleIn
BufferedImage scaled = new BufferedImage(r.width, r.height, BufferedImage.TYPE_INT_RGB
Graphics2D g2 = scaled.createGraphics();
g2.setTransform(scale);
g2.drawImage(image, r.x, r.y, r.width, r.height, this);
Thank you.
> Could you please give more exlanation?
Creates a new image and paints a scaled version of an image onto the new image.
> double ratio = 1;
that won't do any scaling :)
> g2.drawImage(image, r.x, r.y, r.width, r.height, this);
why do u do that?
whats r?
Creates a new image and paints a scaled version of an image onto the new image.
> double ratio = 1;
that won't do any scaling :)
> g2.drawImage(image, r.x, r.y, r.width, r.height, this);
why do u do that?
whats r?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
> graphics2D.setRenderingHin t(Renderin gHints.KEY _INTERPOLA TION,
> RenderingHints.VALUE_INTER POLATION_B ILINEAR);
Thats not necessary with the approach suggested above.
> RenderingHints.VALUE_INTER
Thats not necessary with the approach suggested above.
It's not necessary if you're not interested in the quality of the result
Have you actually ever scaled an image???
kerzner,
The code I posted above will produce excellent quality scaling, but you don't need to specify the size to draw the image in the drawImage() call as that is already handled by the transformation.
Just paint the image whereever you need it.
>>Have you actually ever scaled an image???
I most certainly have. The results are usually lousy. They improve somewhat with hints
I most certainly have. The results are usually lousy. They improve somewhat with hints
you better start using my code then :D
ASKER
Guys, thank you, I am going to try all that early tomorrow morning
ASKER
Ok, good morning.
Dear Objects:
Here is what I am doing now, and I still do not see the image, just empty space
double ratio = .1;
AffineTransform scale = AffineTransform.getScaleIn stance(rat io, ratio);
int w = image.getWidth(null);
int h = image.getHeight(null);
BufferedImage scaled = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB );
Graphics2D g2 = scaled.createGraphics();
g2.setTransform(scale);
g2.drawImage(image, 0, 0, null);
Dear Objects:
Here is what I am doing now, and I still do not see the image, just empty space
double ratio = .1;
AffineTransform scale = AffineTransform.getScaleIn
int w = image.getWidth(null);
int h = image.getHeight(null);
BufferedImage scaled = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB
Graphics2D g2 = scaled.createGraphics();
g2.setTransform(scale);
g2.drawImage(image, 0, 0, null);
You have created an empty image, that's why. Do you want to read one from a file? Where's it meant to come from?
ASKER
I read the image from a tif file using Jimi. When I use regular graphics, I see it. Here is my complete code
if (whichGraphics == 1) {
// regular graphics
g.drawImage(image, r.x, r.y, r.width, r.height, this);
}
else if (whichGraphics == 2) {
// using Graphics2D with hints
Graphics2D g2 = (Graphics2D) g;
RenderingHints hints = new RenderingHints(null);
hints.put(RenderingHints.K EY_INTERPO LATION, RenderingHints.VALUE_INTER POLATION_B ILINEAR);
g2.setRenderingHints(hints );
g2.drawImage(image, r.x, r.y, r.width, r.height, this);
}
else if (whichGraphics == 3) {
// exp exchange advice
double ratio = .1;
AffineTransform scale = AffineTransform.getScaleIn stance(rat io, ratio);
int w = image.getWidth(null);
int h = image.getHeight(null);
BufferedImage scaled = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB );
Graphics2D g2 = scaled.createGraphics();
g2.setTransform(scale);
g2.drawImage(image, 0, 0, null);
}
if (whichGraphics == 1) {
// regular graphics
g.drawImage(image, r.x, r.y, r.width, r.height, this);
}
else if (whichGraphics == 2) {
// using Graphics2D with hints
Graphics2D g2 = (Graphics2D) g;
RenderingHints hints = new RenderingHints(null);
hints.put(RenderingHints.K
g2.setRenderingHints(hints
g2.drawImage(image, r.x, r.y, r.width, r.height, this);
}
else if (whichGraphics == 3) {
// exp exchange advice
double ratio = .1;
AffineTransform scale = AffineTransform.getScaleIn
int w = image.getWidth(null);
int h = image.getHeight(null);
BufferedImage scaled = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB
Graphics2D g2 = scaled.createGraphics();
g2.setTransform(scale);
g2.drawImage(image, 0, 0, null);
}
>>else if (whichGraphics == 2)
Is that block working?
Is that block working?
ASKER
yes, block else if (whichGraphics == 2) is working fine. The quality is only slightly better, almost no difference. I know, that is what you would expect. It also takes a lot of memory and processing.
what color model is the original image using?
ASKER
it is a black and white image
ASKER
I found that this call does the job very well
Image scaledImage = image.getScaledInstance(r. width, r.height, Image.SCALE_SMOOTH);
It runs a bit slow, but produced a very good quality. What would you say?
Image scaledImage = image.getScaledInstance(r.
It runs a bit slow, but produced a very good quality. What would you say?
>>What would you say?
Go for it! ;-)
Go for it! ;-)
> it is a black and white image
Thats possiblty why option 3 was creating empty image as you werre painting to a rgb image.
Thats possiblty why option 3 was creating empty image as you werre painting to a rgb image.
actually the other options paint the iamge to (i assume) the screen whereas that one paints to another image. Compare it with this:
else if (whichGraphics == 3) {
// exp exchange advice
double ratio = .1;
AffineTransform scale = AffineTransform.getScaleIn stance(rat io, ratio);
Graphics2D g2 = (Graphics2D) g;
g2.setTransform(scale);
g2.drawImage(image, 0, 0, null);
}
else if (whichGraphics == 3) {
// exp exchange advice
double ratio = .1;
AffineTransform scale = AffineTransform.getScaleIn
Graphics2D g2 = (Graphics2D) g;
g2.setTransform(scale);
g2.drawImage(image, 0, 0, null);
}
8-)