Link to home
Start Free TrialLog in
Avatar of kerzner
kerznerFlag for United States of America

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.
Avatar of mmuruganandam
mmuruganandam
Flag of United States of America image

Is the exact image is  same size as the displayed one.
Avatar of CEHJ
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
Avatar of kerzner

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
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of kerzner

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.getScaleInstance(ratio, 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.
> 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?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>   graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
>      RenderingHints.VALUE_INTERPOLATION_BILINEAR);

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
you better start using my code then :D
Avatar of kerzner

ASKER

Guys, thank you, I am going to try all that early tomorrow morning
Avatar of kerzner

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.getScaleInstance(ratio, 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);
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?
Avatar of kerzner

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.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                    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.getScaleInstance(ratio, 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);
                }
>>else if (whichGraphics == 2)

Is that block working?
Avatar of kerzner

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?
Avatar of kerzner

ASKER

it is a black and white image
Avatar of kerzner

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?
>>What would you say?

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.
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.getScaleInstance(ratio, ratio);
                    Graphics2D g2 = (Graphics2D) g;
                    g2.setTransform(scale);
                    g2.drawImage(image, 0, 0, null);
                }
8-)