我需要判断图像是否有alpha通道,所以我写这样的代码。
var HaveAlpha = func(Image image.Image) bool {
switch Image.ColorModel() {
case color.YCbCrModel, color.CMYKModel:
return false
case color.RGBAModel:
return !Image.(*image.RGBA).Opaque()
}
// ...
return false
}
因此,我需要列出所有ColorModel
类型并使用Opaque()
来确定图片是否具有Alpha通道(因为我无法在类型{{1}中使用Opaque()
方法直接)。如果图像具有Alpha通道但图像中的所有像素都是不透明的(该图像中的所有RGBA像素都像image.Image
),则此代码可能会返回错误的答案。
在Golang中是否有正确或更好的方法来判断图片是否有alpha通道?
答案 0 :(得分:2)
您可以使用type assertion来检查image.Image
接口类型中存储的具体值是否具有Opaque() bool
方法,如果是,则只需调用它并返回其结果。请注意,image
包中的所有具体图像类型都有Opaque()
方法,因此这将涵盖大多数情况。
如果图像没有这样的Opaque()
方法,则循环图像的所有像素,并检查是否有任何像素具有除0xff
以外的alpha值,这意味着它' s不透明。
请注意,Image.At()
具有一般color.Color
接口类型的返回类型,它只保证单个方法:Color.RGBA()
。此RGBA()
方法返回 alpha-premultiplied 红色,绿色,蓝色和alpha分量,因此如果某个像素具有0xff
alpha值,则该值等于0xffff
时" alpha-premultiplied",这就是我们需要比较的内容。
func Opaque(im image.Image) bool {
// Check if image has Opaque() method:
if oim, ok := im.(interface {
Opaque() bool
}); ok {
return oim.Opaque() // It does, call it and return its result!
}
// No Opaque() method, we need to loop through all pixels and check manually:
rect := im.Bounds()
for y := rect.Min.Y; y < rect.Max.Y; y++ {
for x := rect.Min.X; x < rect.Max.X; x++ {
if _, _, _, a := im.At(x, y).RGBA(); a != 0xffff {
return false // Found a non-opaque pixel: image is non-opaque
}
}
}
return true // All pixels are opaque, so is the image
}
如果图片没有Alpha通道,则上述Opaque()
函数将返回true
,或者它具有所有像素都是不透明的。当且仅当图像具有Alpha通道并且至少有一个像素不是(完全)不透明时,它才会返回false
。
注意:如果图片确实有Opaque()
方法,您可以确定它需要考虑现有像素及其alpha值,例如image.RGBA.Opaque()
与我们上面所做的相似,扫描整个图像;但我们必须以一般方式进行,并且具体图像的Opaque()
实现可能更有效(因此强烈建议使用&#34;运送&#34; Opaque()
方法它是可用的)。例如,image.YCbCr.Opaque()
的实现是一个简单的return true
语句,因为YCbCr
图像没有Alpha通道。