【问题标题】:Converting a 32bpp image to a 16bpp image in Java在 Java 中将 32bpp 图像转换为 16bpp 图像
【发布时间】:2009-07-24 11:25:42
【问题描述】:

如何使用 Java 的库将 32bpp 图像 ( ARGB ) 转换为 16bpp 图像 ( ARGB )?出于我的好奇心,在像素级别,这种转换有什么作用?如果我有一个保存像素值的 int 值(包含所有通道),那么在转换发生后该 int 会有什么不同?

【问题讨论】:

    标签: java image


    【解决方案1】:

    将 32 位 AARRGGBB 值转换为 16 位 ARGB 值将是这样的:

    int argb = ((aarrggbb & 0x000000F0) >> 4)
             | ((aarrggbb & 0x0000F000) >> 8)
             | ((aarrggbb & 0x00F00000) >> 12)
             | ((aarrggbb & 0xF0000000) >> 16);
    

    它将所有内容都保留在低 16 位中,并将高 16 位保留为 0。

    对于每个通道,您会丢失较低的 4 位颜色信息,而较高的颜色信息更重要一些。颜色将被量化为最接近的 4 位等效值,从而在图像上产生视觉上令人不快的色带效果。

    顺便说一下,16 位颜色通常不包含 Alpha 分量。通常(尽管并非总是如此)它分解为红色 5 位,绿色 6 位(因为我们的眼睛对绿色/蓝色最敏感)和蓝色 5 位。

    这种转换将在每个通道上仅丢失 2 或 3 位信息,而不是 4 位,并假定源像素不包含 alpha。

    【讨论】:

    • 感谢详细解释!
    【解决方案2】:

    读入图像并将其保存为您需要的格式。来自http://www.exampledepot.com/egs/javax.imageio/Graphic2File.html

    // Create an image to save
    RenderedImage rendImage = myCreateImage();
    
    // Write generated image to a file
    try {
        // Save as PNG
        File file = new File("newimage.png");
        ImageIO.write(rendImage, "png", file);
    
        // Save as JPEG
        file = new File("newimage.jpg");
        ImageIO.write(rendImage, "jpg", file);
    } catch (IOException e) {
    }
    

    查看 javax.imageio.ImageIO.getWriterFormatNames() 的输出以找到您需要的格式。

    使用 16 bpp 时,每个像素的内部表示不会改变(除了表示丢失),但存储在磁盘上的字节会。

    【讨论】:

    • 将图像保存为 png 或 jpeg 对我有何帮助?
    • 只有在图像文件上谈论 16 bpp 才有意义。 Java 在内存中使用未压缩的图像。如果答案没有意义,您可能需要改写问题。
    猜你喜欢
    • 2023-03-14
    • 2011-09-15
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 2016-03-29
    • 2014-03-17
    • 2013-02-10
    • 2011-03-07
    相关资源
    最近更新 更多