Java: I get a class cast exception error pointing to class I didn't even import
my problem is simple, I have the code I have written to first scale the image down and then crop to desired dimensions (obtained by the Constants class).
if(image != null){
Image originalImage = image.getImage();
int width = Constants.width;
//Algorithm: get the original width and divide with desired width
int height = originalImage.getHeight(null)/(originalImage.getWidth(null)/width);
Image scaledImage = originalImage.getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH);
//Now to crop it to specified dimensions
BufferedImage imageToCrop = (BufferedImage) (java.awt.Image) scaledImage;
height = Constants.height;
imageToCrop = imageToCrop.getSubimage(imageToCrop.getWidth() - width, imageToCrop.getHeight() - height, width, height);
image.setImage(imageToCrop);
}
When run, this is the error I get:
java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
And this corresponds to the line:
BufferedImage imageToCrop = (BufferedImage) (java.awt.Image) scaledImage;
Now I have NOT imported sun.awt anywhere, in fact here is the list of imported items for this class:
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.swing.ImageIcon;
So why does this erro开发者_JS百科r occur? I just don't get it! As you can see I even tried many ways to MANUALLY FORCE THE CAST but still to no avail :(
Any help really appreciated! Thanks!
You didn't import it, but it is a subclass of Image
, and not a subclass of BufferedImage
, so you cannot cast to it.
To create a BufferedImage
from a given Image
, you have to draw the target image on a new instance of BufferedImage
. Check some results from this search
One example from dzone:
public BufferedImage bufferImage(Image image, int type) {
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
Graphics2D g = bufferedImage.createGraphics();
g.drawImage(image, null, null);
waitForImage(bufferedImage);
return bufferedImage;
}
You can't cast it because at runtime your scaledImage has type ToolkitImage, which is not a subclass of BufferedImage.
The Sun class is the actual implementation. You don't need to import it, the toolkit needs to create it. I am not familiar with the guts of that particular part of the library, but it appears that it is not a BufferedImage
.
Also, why do you have two casts here?
BufferedImage imageToCrop = (BufferedImage) (java.awt.Image) scaledImage;
The fact that you've not imported ToolkitImage
does not change the fact that the actualy object returned by getScaledInstance
is an instance of that class. It is a ToolkitImage
whether you want it or not.
I think the thing to do here is to just work with ToolkitImage
and/or find some way to convert it into whatever Image
implementation that you want to work with.
getScaledInstance
doesn't guarantee to return anything more specific than an Image
. You might be lucky and get a BufferedImage
, or you might not. (In theory I don't see anything to say that it's not allowed to return a pseudo-image whose implementation just scales all the dimensions that you pass in and calls the methods on the underlying image to do all the work.)
That aside, you shouldn't really use getScaledInstance
at all, since the other ways of scaling an image are faster and more flexible. You could adapt Bozho's code but substituting your original image, and passing the two extra arguments for the height and width that you want. (You probably also want to set the rendering hint on the graphics context.)
精彩评论