简体   繁体   中英

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 ?

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

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.

SO uh.. now I need to do some research to see if I can get imageType from the Image I got. 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.

Your best bet is to obtain the image using an API that returns a RenderedImage (which can be queried for its 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.

If you just want to convert to a specific ColorModel, ignore what ColorModel the image is using. Create a BufferedImage of the desired type (and size), obtain a Graphics2D to render into it and draw the image into the buffered image.

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:

/**
 * 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.

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.

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;
        }

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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