在Go中合并多个图像

Mic*_*iva 1 image image-processing go

我正在尝试用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()
}
Run Code Online (Sandbox Code Playgroud)

我是Go的新人,我找不到我哪里错了。

icz*_*cza 5

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

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

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

为此,请声明decodedImages为的一个切片image.Image(因为openAndDecode()返回的是type的值image.Image):

var decodedImages = make([]image.Image, len(images))
Run Code Online (Sandbox Code Playgroud)

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

同样,要“结合”具有Alpha通道的图像,还应使用draw.Overoperator。引用博客文章:The Go Blog:The Go image / draw package

Over操作者执行一个源图像的上一个目标图像的自然分层:在改变为目标图像为更小的,其中源(掩蔽之后)是更透明的(即,具有较低的阿尔法)。该Src运营商只是他们无视目标图像的原始内容拷贝源(屏蔽之后)。对于完全不透明的源图像和蒙版图像,这两个运算符会产生相同的输出,但是该Src运算符通常更快。