我想将一个PNG文件拆分为另外4个PNG,其中3个用于RGB,一个Alpha。当我输入PNG时,alpha通道会正确输出,但是RGB通道什么也不会输出。如果我输入JPG,则RGB通道可以正确输出,但是alpha失败,因为没有Alpha通道。
我尝试使用多幅图像,这些图像都是PNG或JPG,但都以我描述的相同方式失败。
val original = ImageIO.read(File("images/input.png"))
val alpha = BufferedImage(original.width, original.height, original.type)
val red = BufferedImage(original.width, original.height, original.type)
val green = BufferedImage(original.width, original.height, original.type)
val blue = BufferedImage(original.width, original.height, original.type)
for (y in 0 until original.height) {
for (x in 0 until original.width) {
val color = original.getRGB(x,y)
val a = color and 0xff000000.toInt()
val r = color and 0x00ff0000
val g = color and 0x0000ff00
val b = color and 0x000000ff
alpha.setRGB(x,y,a)
red.setRGB(x,y,r)
green.setRGB(x,y,g)
blue.setRGB(x,y,b)
}
}
ImageIO.write(alpha,"png", File("images/alpha.png"))
ImageIO.write(red,"png", File("images/red.png"))
ImageIO.write(green,"png", File("images/green.png"))
ImageIO.write(blue,"png", File("images/blue.png"))
我希望单独接收4个带有各自通道的输出,但是我只接收带有PNG的Alpha通道,而不接收带有JPG的Alpha通道。
答案 0 :(得分:1)
setRGB
使用TYPE_INT_ARGB
作为颜色模型。当您的位掩码将Alpha通道设置为0时,图像似乎为空。将alpha设置为ff以显示图像。
val a = color and 0xff000000.toInt()
val r = (color and 0x00ff0000) or 0xff000000.toInt()
val g = (color and 0x0000ff00) or 0xff000000.toInt()
val b = (color and 0x000000ff) or 0xff000000.toInt()
答案 1 :(得分:0)
JPEG文件格式不包含任何Alpha通道-使用JPEG重新创建某种透明度的方法是添加由单色图像组成的另一层,然后通过该图像过滤图像,但这确实很特别用例,在此示例中您很可能不想执行任何操作。
答案 2 :(得分:0)
您的代码无法按预期运行的部分原因是,您根据原始类型创建了新的BufferedImage
:
BufferedImage(original.width, original.height, original.type)
原始类型将根据输入图像而有所不同。对于JPEG,通常为TYPE_3BYTE_BGR
(不包含alpha)。对于PNG,它取决于类型或PNG(灰度,调色板,真彩色,带有或不带有alpha等)。您输入的PNG似乎是带有alpha的真彩色,可能会导致TYPE_4BYTE_ABGR
或TYPE_INT_ARGB
。
相反,您可以使用TYPE_BYTE_GRAY
创建4个灰度图像(只是“级别”),或者像现在一样,使用TYPE_INT_ARGB
创建4个ARGB图像(很抱歉,如果我的Kotlin语法已关闭,我这些天大部分时间都在编程Java):
BufferedImage(original.width, original.height, BufferedImage.TYPE_INT_ARGB)
接下来,如@AlexanderEgger所指出的那样,set/getRGB
方法以压缩的ARGB格式运行,因此您需要确保颜色不透明(and
仅使用 彩色遮罩,将产生完全透明的颜色):
val a = color and 0xff000000.toInt()
val r = (color and 0x00ff0000) or 0xff000000.toInt()
val g = (color and 0x0000ff00) or 0xff000000.toInt()
val b = (color and 0x000000ff) or 0xff000000.toInt()
或者,如果您喜欢关卡方法,则按照@MarkSetchell的建议进行操作,并创建所有灰度图像(同样,Kotlin语法可能略有偏离):
BufferedImage(original.width, original.height, BufferedImage.TYPE_BYTE_GRAY)
...
val a = (color >> 24) and 0xff
val r = (color >> 16) and 0xff
val g = (color >> 8) and 0xff
val b = color and 0xff
val aa = 0xff000000.toInt() or (a << 16) or (a << 8) or a
val rr = 0xff000000.toInt() or (r << 16) or (r << 8) or r
val gg = 0xff000000.toInt() or (g << 16) or (g << 8) or g
val bb = 0xff000000.toInt() or (b << 16) or (b << 8) or b
(并将aa
,rr
,gg
和bb
传递到setRGB
)。