在Go中合并多个图像

时间:2019-02-11 11:21:05

标签: image go image-processing

我正在尝试用Go合并N个图像的数组(其中N将是一个动态值),但结果总是得到黑色图像。

这是我的代码:

package main

import (
    "image"
    "image/draw"
    "image/jpeg"
    "image/png"
    "log"
    "os"
)

func openAndDecode(imgPath string) image.Image {
    img, err := os.Open(imgPath)
    if err != nil {
        log.Fatalf("Failed to open %s", err)
    }

    decoded, err := png.Decode(img)
    if err != nil {
        log.Fatalf("Failed to decode %s", err)
    }
    defer img.Close()

    return decoded
}

func main () {
    var images = [4]string{"background", "shadow", "item1 ", "item2"}
    var decodedImages = [4]*image.RGBA{}

    for i, img := range images {
        decodedImage := openAndDecode("./imgs/" + img + ".png")
        bounds := decodedImage.Bounds()
        newImg := image.NewRGBA(bounds)
        decodedImages[i] = newImg
    }

    bounds := decodedImages[0].Bounds()
    newImage := image.NewRGBA(bounds)

    for _, img := range decodedImages {
        draw.Draw(newImage, img.Bounds(), img, image.ZP, draw.Src)
    }

    result, err := os.Create("result.jpg")
    if err != nil {
        log.Fatalf("Failed to create: %s", err)
    }

    jpeg.Encode(result, newImage, &jpeg.Options{jpeg.DefaultQuality})
    defer result.Close()
}

我是Go的新手,我找不到我哪里错了。 非常感谢!

1 个答案:

答案 0 :(得分:4)

在加载图像的第一个循环中,您还将创建一个新的空白图像,并将该空白图像存储在decodedImages中。然后,您遍历这些空图像并将其合并。

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

for i, img := range images {
    decodedImages[i] = openAndDecode("./imgs/" + img + ".png")
}

为此,请声明decodedImagesimage.Image的一部分(因为openAndDecode()返回类型为image.Image的值):

var decodedImages = make([]image.Image, len(images))

此外,每当打开文件并检查错误时,都应立即推迟关闭,这样,如果后续代码失败,文件仍将关闭。

要使图像与Alpha通道“结合”,还应使用draw.Over运算符。引用博客文章:The Go Blog: The Go image/draw package

  

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