Объединить несколько изображений в Go - PullRequest
0 голосов
/ 11 февраля 2019

Я пытаюсь объединить массив из N изображений (где N будет динамическим значением) с Go, но в результате я всегда получаю черное изображение.

Вот мой код:

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 голосов
/ 11 февраля 2019

В первом цикле, в который вы загружаете изображения, вы также создаете новое пустое изображение и сохраняете это пустое изображение в decodedImages.И затем вы перебираете эти пустые изображения и объединяете их.

Вместо этого вы должны сохранить загруженные изображения в decodedImages:

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

Чтобы это работало, объявите decodedImages какфрагмент image.Image (поскольку openAndDecode() возвращает значение типа image.Image):

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

Кроме того, всякий раз, когда вы открываете файл и проверяете ошибку, вы должны отложить его сразу послеесли последующий код завершится ошибкой, файл все равно закроется.

Также, чтобы «объединить» изображения с альфа-каналом, вы должны использовать оператор draw.Over.Цитата из поста блога: The Go Blog: пакет изображений / изображений Go :

Оператор Over выполняет естественное наложение исходного изображения на конечное изображение:изменение к целевому изображению меньше, когда источник (после маскировки) более прозрачен (то есть имеет более низкую альфу).Оператор Src просто копирует источник (после маскировки), не обращая внимания на исходный контент конечного изображения.Для полностью непрозрачных изображений источника и маски оба оператора выдают одинаковый вывод, но оператор Src обычно работает быстрее.

...