Solved

Quality of reduced images

Posted on 2004-04-21
26
385 Views
Last Modified: 2010-08-05
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.
0
Comment
Question by:kerzner
  • 9
  • 8
  • 8
  • +1
26 Comments
 
LVL 9

Expert Comment

by:mmuruganandam
ID: 10879272
Is the exact image is  same size as the displayed one.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10879273
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
0
 
LVL 1

Author Comment

by:kerzner
ID: 10879566
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
0
 
LVL 92

Accepted Solution

by:
objects earned 250 total points
ID: 10883528
AffineTransform scale = AffineTransform.getScaleInstance(ratio, ratio);
BufferedImage scaled = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = scaled.createGraphics();
g.setTransform(scale);
g.drawImage(i, 0, 0, null);
0
 
LVL 1

Author Comment

by:kerzner
ID: 10883656
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.
0
 
LVL 92

Expert Comment

by:objects
ID: 10883719
> 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?
0
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 250 total points
ID: 10884133
You should set rendering hints if you're going to use the standard api or you'll end up with precisely the same deterioration:



    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
      RenderingHints.VALUE_INTERPOLATION_BILINEAR);
   
That's taken from an example of producing a thumbnail at http://www.geocities.com/marcoschmidt.geo/java-save-jpeg-thumbnail.html

If you're going to save the image again you can use ImageIO.write rather than that JPEGEncoder stuff nowadays
0
 
LVL 92

Expert Comment

by:objects
ID: 10884211
>   graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
>      RenderingHints.VALUE_INTERPOLATION_BILINEAR);

Thats not necessary with the approach suggested above.

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10884233
It's not necessary if you're not interested in the quality of the result
0
 
LVL 92

Expert Comment

by:objects
ID: 10884274

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.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10884289
>>Have you actually ever scaled an image???

I most certainly have. The results are usually lousy. They improve somewhat with hints
0
 
LVL 92

Expert Comment

by:objects
ID: 10884310
you better start using my code then :D
0
 
LVL 1

Author Comment

by:kerzner
ID: 10885142
Guys, thank you, I am going to try all that early tomorrow morning
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Author Comment

by:kerzner
ID: 10889501
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);
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10889524
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?
0
 
LVL 1

Author Comment

by:kerzner
ID: 10889701
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);
                }
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10889799
>>else if (whichGraphics == 2)

Is that block working?
0
 
LVL 1

Author Comment

by:kerzner
ID: 10889935
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.
0
 
LVL 92

Expert Comment

by:objects
ID: 10894587
what color model is the original image using?
0
 
LVL 1

Author Comment

by:kerzner
ID: 10900025
it is a black and white image
0
 
LVL 1

Author Comment

by:kerzner
ID: 10900260
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?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10904720
>>What would you say?

Go for it! ;-)
0
 
LVL 92

Expert Comment

by:objects
ID: 10904748
> it is a black and white image

Thats possiblty why option 3 was creating empty image as you werre painting to a rgb image.
0
 
LVL 92

Expert Comment

by:objects
ID: 10904772
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);
                }
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10904891
8-)
0
 
LVL 92

Expert Comment

by:objects
ID: 10905063
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now