JR Wink
JR Wink

Reputation: 107

Append images without creating temporary files with Golang and imagemagick. Is it possible?

I would like to append images without creating temporary files with Golang and imagemagick. Is it possible to do something like this ?

Seems like i can't have multiple stdin.

func main() {
    var output bytes.Buffer

    buff1 := new(bytes.Buffer)
    f1, _ := os.Open("image/1.png")
    defer f1.Close()
    img1, _, _ := image.Decode(f1)
    png.Encode(buff1, img1)

    buff2 := new(bytes.Buffer)
    f2, _ := os.Open("image/2.png")
    defer f1.Close()
    img2, _, _ := image.Decode(f2)
    png.Encode(buff2, img2)

    buff3 := new(bytes.Buffer)
    f3, _ := os.Open("image/3.png")
    defer f1.Close()
    img3, _, _ := image.Decode(f3)
    png.Encode(buff3, img3)

    cmd := exec.Command("convert", []string{"png:-", "png:-", "+append", "png:-"}...)

    cmd.Stdin = bytes.NewReader(buff1.Bytes())
    // ? buff2.Bytes()
    // ? buff3.Bytes()

    cmd.Stdout = &output
    if err := cmd.Run(); err != nil {
        fmt.Println("failed: %w", err)
    }
    fmt.Println(len(output.Bytes()))
    imgPng, _, _ := image.Decode(bytes.NewReader(output.Bytes()))
    out, _ := os.Create("result.png")
    png.Encode(out, imgPng)

}

Upvotes: 1

Views: 534

Answers (1)

mpx
mpx

Reputation: 1354

You can use this approach on most modern Unix OSes:

For each file:

  • Create a pipe via os.Pipe
  • Create a goroutine to write your image data into the write pipe *os.File and close it when finished.
  • Append each read pipe *os.File to exec.Cmd.ExtraFiles. The first file/pipe will be accessible via /dev/fd/3, then /dev/fd/4, etc..

You will also need to ensure the goroutines are released if there is an error by closing each pipe *os.File afterwards.

This is reasonably complex, and not totally portable. It's a bit simpler to just create temporary files (eg, via os.CreateTemp) and cleanup afterwards. In practice these files may be stored on a memory filesystem anyway (eg, when /tmp is using tmpfs).

Upvotes: 1

Related Questions