Reputation: 107
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
Reputation: 1354
You can use this approach on most modern Unix OSes:
For each file:
os.Pipe
*os.File
and close it when finished.*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