【问题标题】:How to get ColorSpace of java.awt.Image?如何获取 java.awt.Image 的 ColorSpace?
【发布时间】:2012-08-15 15:06:54
【问题描述】:

我知道当我使用BufferedImage 时,我可以致电BufferedImage.getColorModel() 但是当我只有一个 java.awt.Image 的实例时,如何获得相同的值?

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

已更新..

好吧。现在让我准确解释一下我想要实现的目标:

我想创建一种方法来创建图像的缩略图。

首先,我将其转换为JPEG 文件格式图像并将结果写入文件, 然后我发现如果我这样做我会失去原始图像的透明度, 所以我试图将目标图像保存为PNG文件格式并将BufferedImage标记为TYPE_BYTE_INDEXED以减小目标文件大小,但最后我意识到如果现在原始图像本身包含很多颜色,那么我因为TYPE_BYTE_INDEXED 不能包含很多颜色,所以会得到一个粗糙质量的目标图像。

所以呃.. 现在我需要做一些研究,看看我是否可以从我得到的Image 中得到imageType。 如果imageType 最初是TYPE_BYTE_INDEXED,那么我也可以在目标图像上使用TYPE_BYTE_INDEXED,否则我可以使用TYPE_BYTE_ARGBTYPE_BYTE_RGB(这取决于原始图像的原始值)来确保我将一个高质量的缩略图和一个较小尺寸的图像目标文件。

【问题讨论】:

    标签: java image colors awt


    【解决方案1】:

    最好的办法是使用返回 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 支持的任何格式保存缩略图。

    【讨论】:

    • 是的。但是当我使用 BufferedImage(int width,int height,int imageType) 将 Image 转换为 BufferedImage 时,我应该知道原始图像的 imageType,然后我可以确定是否可以使用 BufferedImage .TYPE_BYTE_INDEXED 来减小目标图像大小。
    • 那为什么要转换它呢?与其在每个答案中更改问题/要求,不如告诉我们您想要实现的目标?
    【解决方案2】:

    我不知道具体是什么方法,但如果您可以在 BufferdImage 上使用此方法,请尝试将您的 java.awt.Image 转换为 BufferedImage

    【讨论】:

    • 现在我需要知道如何将 ColorModel 更改为 BufferedImage 的 imageType(int width,int height,int imageType)
    • 看看here。希望我正确理解了你的问题。
    【解决方案3】:
    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;
            }
    
        }
    

    【讨论】:

      猜你喜欢
      • 2021-04-19
      • 1970-01-01
      • 2013-04-02
      • 2011-09-14
      • 2010-09-13
      • 2010-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多