简体   繁体   English

如何获取java.awt.Image的ColorSpace?

[英]How to get ColorSpace of java.awt.Image?

I know that when I'm using BufferedImage I can call BufferedImage.getColorModel() but how can I get the same value when I only have an instance of java.awt.Image ? 我知道当我使用BufferedImage可以调用BufferedImage.getColorModel()但是当我只有java.awt.Image实例时如何获得相同的值?

==================================================================================== ================================================== =================================

UPDATED.. 更新..

OK so . 好吧。 now let me explain extactly what i wanna achieve: 现在让我确切地解释我想要实现的目标:

I want to create a method to create some thumbnail of a image. 我想创建一种创建图像缩略图的方法。

At first , I convert it to a JPEG file format image and write the result to file, And then I found if I do that I will lose the original image's transparency, So I'm trying to save the target image as PNG file format and mark the BufferedImage as TYPE_BYTE_INDEXED to reduce the size of target file size, but finally i realized if now the original image itself contains lots of color, then I will get a rough quality target image because TYPE_BYTE_INDEXED can't contains lots color. 首先,我将其转换为JPEG文件格式的图像并将结果写入文件,然后发现如果这样做,我将失去原始图像的透明度,因此我尝试将目标图像另存为PNG文件格式,将BufferedImage标记为TYPE_BYTE_INDEXED以减小目标文件大小的大小,但是最后我意识到,如果现在原始图像本身包含很多颜色,那么我将获得质量较粗糙的目标图像,因为TYPE_BYTE_INDEXED不能包含很多颜色。

SO uh.. now I need to do some research to see if I can get imageType from the Image I got. 所以,..现在我需要做一些研究,看看是否可以从所获取的Image获取imageType if the imageType is originally TYPE_BYTE_INDEXED then I can use TYPE_BYTE_INDEXED also on the target image , otherwise I can use TYPE_BYTE_ARGB or TYPE_BYTE_RGB (it depends on the origin value of the original image ) to make sure that I will a high quality thumbnail and a smaller size image target file. 如果imageType最初是TYPE_BYTE_INDEXED那么我也可以在目标图像上使用TYPE_BYTE_INDEXED ,否则我可以使用TYPE_BYTE_ARGBTYPE_BYTE_RGB (取决于原始图像的原始值)来确保我将获得高质量的缩略图和较小的尺寸图像目标文件。

Your best bet is to obtain the image using an API that returns a RenderedImage (which can be queried for its ColorModel). 最好的选择是使用返回RenderedImage的API获取图像(可以查询其ColorModel)。 Since java.awt.Image does not supply any methods to query for its ColorModel, any guessing game would involve examining the concrete implementing class - and that may well be implementation dependent. 由于java.awt.Image不提供任何查询其ColorModel的方法,因此任何猜谜游戏都将涉及检查具体的实现类-可能与实现有关。

If you just want to convert to a specific ColorModel, ignore what ColorModel the image is using. 如果只想转换为特定的ColorModel,请忽略图像使用的ColorModel。 Create a BufferedImage of the desired type (and size), obtain a Graphics2D to render into it and draw the image into the buffered image. 创建所需类型(和大小)的BufferedImage,获取Graphics2D渲染到其中,然后将图像绘制到缓冲的图像中。

EDIT: In response to 'Create a thumbnail' 编辑:响应“创建缩略图”

First, even if the original image is using an indexed color model, you still need to use a direct color model for the thumbnail - scaling an indexed color image will produce mixed colors (due to pixel averaging) that are most likely not contained in the color map of the original. 首先, 即使原始图像是使用一个索引颜色模型,你仍然需要使用直接颜色模型的缩略图-缩放索引彩色图像会产生混合色(由于象素平均)是最有可能包含在原始颜色图。 If you really want to go the extra mile, you have to analyze the pixel data of the thumbnail to decide if you can use an indexed color model. 如果您真的想加倍努力,则必须分析缩略图的像素数据,以决定是否可以使用索引颜色模型。

There is a half-reliable method to determine if the source image has an alpha channel: 有一种半可靠的方法来确定源图像是否具有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;
    }
}

This may fail with obscure image types, but for generating a thumbnail its usually good enough. 这可能会因图像类型不清晰而失败,但是对于生成缩略图通常足够好了。 After you have determined if there is alpha, just chose an appropiate BufferedImage.TYPE for the thumbnail, TYPE_INT_ARGB or TYPE_INT_RGB. 确定是否存在Alpha后,只需为缩略图TYPE_INT_ARGB或TYPE_INT_RGB选择一个合适的BufferedImage.TYPE。

Then render the image into the thumbnail image (this is a verbose example): 然后将图像渲染为缩略图图像(这是一个冗长的示例):

    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();

Calculating proper width and height for the thumbnail is left as an exercise to the reader. 留给读者练习是为缩略图计算正确的宽度和高度。 The thumbnail image can then be saved using ImageIO in any format ImageIO supports. 然后可以使用ImageIO支持的任何格式的ImageIO保存缩略图。

BufferdImage知道该方法是什么,但是如果可以在BufferdImage上使用此方法, BufferdImage尝试将java.awt.Image转换为BufferedImage

protected static BufferedImage toBufferedImage(Image image) {

        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        } else {

            int w = image.getWidth(null);
            int h = image.getHeight(null);

            BufferedImage bi = new BufferedImage(w, h,
                    BufferedImage.TYPE_INT_RGB);

            Graphics graphics = bi.getGraphics();
            graphics.drawImage(image, 0, 0, w, h, Color.WHITE, null);
            graphics.dispose();

            return bi;
        }

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM