Image 在Go中合并多个图像

Image 在Go中合并多个图像,image,go,image-processing,Image,Go,Image Processing,我试图将一个由N个图像组成的数组(其中N是一个动态值)与Go合并,但结果总是得到一个黑色图像 这是我的密码: 主程序包 进口( “图像” “图像/绘图” “图像/jpeg” “图像/png” “日志” “操作系统” ) func openAndDecode(imgPath字符串)image.image{ img,err:=os.Open(imgPath) 如果错误!=零{ log.Fatalf(“打开%s失败”,错误) } 已解码,错误:=png.Decode(img) 如果错误!=零{ log

我试图将一个由N个图像组成的数组(其中N是一个动态值)与Go合并,但结果总是得到一个黑色图像

这是我的密码:

主程序包
进口(
“图像”
“图像/绘图”
“图像/jpeg”
“图像/png”
“日志”
“操作系统”
)
func openAndDecode(imgPath字符串)image.image{
img,err:=os.Open(imgPath)
如果错误!=零{
log.Fatalf(“打开%s失败”,错误)
}
已解码,错误:=png.Decode(img)
如果错误!=零{
log.Fatalf(“解码%s失败”,错误)
}
延迟img.Close()
返回解码
}
func main(){
var images=[4]字符串{“背景”、“阴影”、“项目1”、“项目2”}
var decodedImages=[4]*image.RGBA{}
对于i,img:=范围图像{
decodedImage:=openAndDecode(“./imgs/”+img+“.png”)
bounds:=decodedImage.bounds()
newImg:=image.NewRGBA(边界)
decodedImages[i]=newImg
}
bounds:=decodedImages[0]。bounds()
newImage:=image.NewRGBA(边界)
对于u,img:=范围解码图像{
draw.draw(newImage,img.Bounds(),img,image.ZP,draw.Src)
}
result,err:=os.Create(“result.jpg”)
如果错误!=零{
log.Fatalf(“未能创建:%s”,错误)
}
jpeg.Encode(结果、新图像和&jpeg.Options{jpeg.DefaultQuality})
延迟结果。关闭()
}

我是个新手,我不知道我错在哪里。

在加载图像的第一个循环中,您还创建了一个新的空图像,并将此空图像存储在
decodedImages
中。然后在这些空图像上迭代并合并它们

相反,您应该将加载的图像存储在
decodedImages

for i, img := range images {
    decodedImages[i] = openAndDecode("./imgs/" + img + ".png")
}
为此,请将
decodedImages
声明为
image.image
(因为
openAndDecode()
返回类型为
image.image
的值):

此外,每当您打开一个文件并检查错误时,您应该立即延迟关闭它,因此如果后续代码失败,该文件仍将关闭

此外,要将图像与alpha通道“组合”,应使用
draw.Over
操作符。引用博文:

Over
操作符在目标图像上执行源图像的自然分层:在源(掩蔽后)更透明(即,具有较低的alpha)的位置,对目标图像的更改较小。
Src
操作符仅复制源图像(掩蔽后),而不考虑目标图像的原始内容。对于完全不透明的源图像和遮罩图像,这两个操作符产生相同的输出,但是
Src
操作符通常更快


非常感谢@icza,解释得非常清楚!现在,PNG透明层似乎已转换为黑色,因此,将多个图像合并为一个黑色图像,并在其上打印最后一层。我的错误是,我使用了
draw.Src
而不是
draw.Over
。再次感谢你@是的,你必须使用
draw.Over
。有关详细介绍,请参阅博客文章:
var decodedImages = make([]image.Image, len(images))