最好的办法是使用返回 RenderedImage(可以查询其 ColorModel)的 API 来获取图像。由于 java.awt.Image 不提供任何方法来查询它的 ColorModel,任何猜谜游戏都将涉及检查具体的实现类——这很可能是依赖于实现的。
如果您只想转换为特定的 ColorModel,请忽略图像使用的 ColorModel。创建所需类型(和大小)的 BufferedImage,获取 Graphics2D 以渲染到其中并将图像绘制到缓冲图像中。
编辑:响应“创建缩略图”
首先,即使原始图像使用索引颜色模型,您仍然需要为缩略图使用直接颜色模型 - 缩放索引颜色图像会产生混合颜色(由于像素平均),这些颜色很可能不包含在原图的彩色图。如果你真的想加倍努力,你必须分析缩略图的像素数据来决定是否可以使用索引颜色模型。
有一种半可靠的方法来确定源图像是否具有 alpha 通道:
/**
* Returns true if image has alpha channel
*/
public static boolean hasAlpha(final Image image) {
// If buffered image, the color model is readily available
if (image instanceof RenderedImage) {
return ((RenderedImage) image).getColorModel().hasAlpha();
}
// Use a pixel grabber to retrieve the image's color model;
// grabbing a single pixel is usually sufficient
final PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, 1, 1, false);
try {
pixelGrabber.grabPixels();
return pixelGrabber.getColorModel().hasAlpha();
} catch (final Exception e) {
return true;
}
}
对于模糊的图像类型,这可能会失败,但对于生成缩略图,它通常就足够了。在确定是否有 alpha 后,只需为缩略图选择一个合适的 BufferedImage.TYPE,TYPE_INT_ARGB 或 TYPE_INT_RGB。
然后将图像渲染成缩略图(这是一个详细的示例):
final boolean hasAlpha = hasAlpha(image);
final int imageType = hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
final BufferedImage thumbnail = new BufferedImage(width, height, imageType);
final Graphics2D g = thumbnail.createGraphics();
// set rendering hints according to desired quality
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
if (!hasAlpha) {
g.drawImage(image, 0, 0, width, height, Color.WHITE, (ImageObserver) null);
} else {
g.drawImage(image, 0, 0, width, height, (ImageObserver) null);
}
g.dispose();
计算缩略图的适当宽度和高度留给读者作为练习。然后可以使用 ImageIO 以 ImageIO 支持的任何格式保存缩略图图像。