Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
367 views
in Technique[技术] by (71.8m points)

java - Scale a BufferedImage the fastest and easiest way

The task: I have some images, I scale them down, and join them to one image. But I have a little problem with the implementation:

The concrete problem: I want to resize/scale a BufferedImage. The getScaledInstance method returns an Image object, but I can't cast it to BufferedImage:

Exception in thread "main" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage

(I don't know why is it a ToolkitImage instead of an Image...)

I found a solution:

Image tmp = bi.getScaledInstance(SMALL_SIZE, SMALL_SIZE, BufferedImage.SCALE_FAST);
BufferedImage buffered = new BufferedImage(SMALL_SIZE,SMALL_SIZE,BufferedImage.TYPE_INT_RGB);
buffered.getGraphics().drawImage(tmp, 0, 0, null);

But it's slow, and I think there should be a better way to do it.

I need the BufferedImage, because I have to get the pixels to join the small images.

Is there a better (nicer/faster) way to do it?

EDIT: If I cast the Image first to ToolkitImage, it has a getBufferedImage() method. But it always returns null. Do you know why?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The Graphics object has a method to draw an Image while also performing a resize operation:

Graphics.drawImage(Image, int, int, int, int, ImageObserver) method can be used to specify the location along with the size of the image when drawing.

So, we could use a piece of code like this:

BufferedImage otherImage = // .. created somehow
BufferedImage newImage = new BufferedImage(SMALL_SIZE, SMALL_SIZE, BufferedImage.TYPE_INT_RGB);

Graphics g = newImage.createGraphics();
g.drawImage(otherImage, 0, 0, SMALL_SIZE, SMALL_SIZE, null);
g.dispose();

This will take otherImage and draw it on the newImage with the width and height of SMALL_SIZE.


Or, if you don't mind using a library, Thumbnailator could accomplish the same with this:

BufferedImage newImage = Thumbnails.of(otherImage)
                             .size(SMALL_SIZE, SMALL_SIZE)
                             .asBufferedImage();

Thumbnailator will also perform the resize operation quicker than using Image.getScaledInstance while also performing higher quality resize operations than using only Graphics.drawImage.

Disclaimer: I am the maintainer of the Thumbnailator library.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...