Loaded images won't anti-alias.

Hey everybody,

I’ve got a question here. Whenever I use a Graphics2D object with RenderingHints.KEY_ANTIALIAS set to ON, it won’t anti-alias images loaded by using Toolkit.getImage(String). Can it only anti-alias drawn shapes, or is there some other setting I need to set to anti-alias drawn images?

Here’s some code:

private Graphics2D screen;
private BufferedImage buffer;

private Image drawnImage;

...

// Called before any rendering is done, obviously.
private void initBuffer() {
	// Back buffer
	buffer = new BufferedImage(640, 480, 	BufferedImage.TYPE_INT_ARGB);
	screen = (Graphics2D)buffer.getGraphics();

	// Turn anti-aliasing ON
	screen.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.KEY_ANTIALIAS_ON);

	// Load an image to be drawn.
	drawnImage = Toolkit.getDefaultToolkit().getImage("Car.png");
}

// The rendering loop. The screen object is drawn to a JPanel's
// Graphics object in the paintComponent() method. After the buffer
// is cleared in the paintComponent() method, it calls this method
// to draw the image to the Graphics2D object (screen).
private void render() {
	screen.drawImage(drawnImage, 50, 50, this);
}

Thanks,
Jamison

erm, unless you are performing a transformation on the image, anti-aliasing will have no effect what-so-ever.

Simplisticly, anti-aliasing gives you sub-pixel rendering accuracy by interpolating the pixel colors of neighbouring pixels.

If you are performing no transformation, the source raster and the destination raster map perfectly onto one-another, there will be no aliasing to… errrr…anti!

So, it can’t be done?

What you are looking for is soft clipping. See Chris Campbell’s blog -

http://weblogs.java.net/blog/campbell/

he also did another article today!

Keith.

The only reason his so called “soft clipping” is anti-aliased is because he’s drawing shapes; not images like what I need. I can anti-alias shapes perfectly fine (e.g. if I use fillOval()) but not if I use drawImage() to draw a loaded image.

You haven’t told us what you are doing - scaling the images, clipping them or what? If you’re not doing either the only way you can get rid of jaggies in your images is to get better images in the first place.

Images (.jpg, .gif) are bitmaps - they can’t be anti-aliased. If you are scaling them to be bigger, they can be ‘interpolated’ - not the same as anit-aliased. Anti-aliasing can only be done on Vector graphics I think, like your Shapes. If you’re clipping then you can use campbell’s work-around soft-clipping technique.

Alternatively, I think there’s a new vector-image standard called SVG out there that you could use, but such an image would be just like drawing shapes in java.

Keith.

What kind of image are you loading and how is it supposed to look like?

You cant take some aliased image and make it antialiased. The required information simply isnt there. If you render 3d stuff for example, you have lots of information… you can either sample only the centers of the pixels, which give you some aliased image or you can take more samples (=more information) per pixel and average that for antialiasing.

For example some black pixel in some aliased image can be pretty much anything… from solid black to some almost non existing black spot at the sampling position.

yes, oNyx is exactly right. that is why vector objects (think SVG or Flash) are “inifitely” zoomable. a raster image (jpg gif,png, etc) are just pixels, the program doesn’t really know what the pixels represent, it just zooms on them. raster images can be somewhat improved with techniques such as bilinear filtering.

vector images (svg/flash) don’t think “I’m zooming in on pixels,” they think “I’m zooming in on a circle that is width x height big at normal zoom.” - and when it zooms, it recalculates the radians and everything that is involved in a circle so that it fills up all the new space that is added when you zoom on something. this of course isnt limited to circles, it’s (un)limited to any kind of vector. circles and curves are a bit of a “special” object in vector imaging, most every other shape is defined by several solid lines.

of course, if you used a bunch of colored rectangles to define imagery in a vector format, you’d be back at square one, because then the vector program will be doing exactly what the raster program is doing: moving rectangular colors around. =)

Ahh okay. And by the way, the images are drawn to a BufferedImage with a Graphics2D object, and the Graphics2D object is rotated (to rotate the whole game area). That’s why I couldn’t just anti-alias my images to start with, because they get jaggy when it’s rotated. But if it can’t be done, then that’s alright, I can live with it. Anywho, thanks everybody, I appreciate it.

Ah, well you didn’t mention that your Graphics2D is being rotated. That does help explain why you’re worried about antialiasing. Anyway, as others have said in this thread, antialiasing doesn’t apply to image rendering, but I suspect what you’re after is some way to smooth the image when it is rotated, so try this:


    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

Chris