Golang how to concatenate/append images to one another

Issue

Go has great image manipulation and data libraries however I’m having trouble creating one big image from smaller ones. Does anyone know how to take two png or jpeg files in Golang and concatenate them to form one big image that encompasses the two (or more) files?

i’m currently reading png files like so:

imgFile, err := os.Open(path)
if err != nil {
    return Image{}, err
}
img, _, err := image.Decode(imgFile)
if err != nil {
    return Image{}, err
}

rgba := image.NewRGBA(img.Bounds())
if rgba.Stride != rgba.Rect.Size().X*4 {
    return Image{}, fmt.Errorf("unsupported stride")
}
draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)

I’m confused on how to take this png RGBA data and concatenate with other RGBA data and/or combine that into an “empty” image.

Solution

Create a new empty image (NewRGBA) that has bounds large enough to hold both images. Then use the Draw method to draw each image on appropriate parts of this new large image.

Here are steps with code.

Load two images.

imgFile1, err := os.Open("test1.jpg")
if err != nil {
    fmt.Println(err)
}
imgFile2, err := os.Open("test2.jpg")
if err != nil {
    fmt.Println(err)
}
img1, _, err := image.Decode(imgFile1)
if err != nil {
    fmt.Println(err)
}
img2, _, err := image.Decode(imgFile2)
if err != nil {
    fmt.Println(err)
}

Let’s draw the second image to the right of the first image. So the starting point of it should be at (w, 0) where w is the width of the first image. The bottom right point of the first image will be the bottom left point of the second.

//starting position of the second image (bottom left)
sp2 := image.Point{img1.Bounds().Dx(), 0}

It should be in a rectangle large enough to hold it.

//new rectangle for the second image
r2 := image.Rectangle{sp2, sp2.Add(img2.Bounds().Size())}

Now create a large rectangle that will be wide enough to hold both images.

//rectangle for the big image
r := image.Rectangle{image.Point{0, 0}, r2.Max}

Note This large image will have the height of the second image. If the first image is higher it will be cropped.

Create a new image.

rgba := image.NewRGBA(r)

Now you can draw the two images into this new image

draw.Draw(rgba, img1.Bounds(), img1, image.Point{0, 0}, draw.Src)
draw.Draw(rgba, r2, img2, image.Point{0, 0}, draw.Src)

Since we created r2 so its to the right of the first image, second image will be drawn to the right.

Finally you can export it.

out, err := os.Create("./output.jpg")
if err != nil {
    fmt.Println(err)
}

var opt jpeg.Options
opt.Quality = 80

jpeg.Encode(out, rgba, &opt)

Answered By – Aruna Herath

Answer Checked By – Dawn Plyler (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.