package main import ( "fmt" "image" "image/draw" "image/jpeg" "os" "github.com/oliamb/cutter" "go.oneofone.dev/resize" ) /** "431" "697" "2514" "2047" zoom: 0.392 816 528 ------------- "153" "9" "1331" "772" zoom: 0.6949 816 528 */ func main() { const width = 816 * 4 const height = 528 * 4 imgFile1, err := os.Open("img1.jpg") if err != nil { fmt.Println(err) } imgFile2, err := os.Open("img2.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) } img1, err = cutter.Crop(img1, cutter.Config{ Width: 2514 - 431, Height: 2047 - 697, Anchor: image.Point{431, 697}, Mode: cutter.TopLeft, // optional, default value }) if err != nil { panic(err) } img1 = resize.Resize(width, height, img1, resize.Lanczos3) img2, err = cutter.Crop(img2, cutter.Config{ Width: 1331 - 153, Height: 772 - 9, Anchor: image.Point{153, 9}, Mode: cutter.TopLeft, // optional, default value }) if err != nil { panic(err) } img2 = resize.Resize(width, height, img2, resize.Lanczos3) //starting position of the second image (bottom left) //sp2 := image.Point{img1.Bounds().Dx(), 0} //new rectangle for the second image //r2 := image.Rectangle{sp2, sp2.Add(img2.Bounds().Size())} //rectangle for the big image r := image.Rectangle{image.Point{0, 0}, image.Point{width, height + height}} r2 := image.Rectangle{image.Point{0, height + 1}, image.Point{width, height + height}} rgba := image.NewRGBA(r) draw.Draw(rgba, img1.Bounds(), img1, image.Point{0, 0}, draw.Src) draw.Draw(rgba, r2, img2, image.Point{0, 0}, draw.Src) out, err := os.Create("./output.jpg") if err != nil { fmt.Println(err) } var opt jpeg.Options opt.Quality = 80 jpeg.Encode(out, rgba, &opt) }