You've already forked collage-maker
							
							add Make collage
This commit is contained in:
		@@ -3,10 +3,13 @@ package collage
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"image"
 | 
						"image"
 | 
				
			||||||
 | 
						"image/draw"
 | 
				
			||||||
 | 
						"image/jpeg"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"io/fs"
 | 
						"io/fs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"go.oneofone.dev/resize"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Dimension struct {
 | 
					type Dimension struct {
 | 
				
			||||||
@@ -31,24 +34,53 @@ func (r Rectangle) ToImgRect() image.Rectangle {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Photo struct {
 | 
				
			||||||
 | 
						ImageName string    `json:"image"`
 | 
				
			||||||
 | 
						Crop      Rectangle `json:"crop"`
 | 
				
			||||||
 | 
						Frame     Rectangle `json:"frame"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Request struct {
 | 
					type Request struct {
 | 
				
			||||||
	BackgroundImage string    `json:"background_image"`
 | 
						BackgroundImage string    `json:"background_image"`
 | 
				
			||||||
	Aspect          Dimension `json:"aspect"`
 | 
						Aspect          Dimension `json:"aspect"`
 | 
				
			||||||
	Dimension       Dimension `json:"dimension"`
 | 
						Dimension       Dimension `json:"dimension"`
 | 
				
			||||||
	Photos          []struct {
 | 
						Photos          []Photo   `json:"photos"`
 | 
				
			||||||
		ImageName string    `json:"image"`
 | 
					 | 
				
			||||||
		Crop      Rectangle `json:"crop"`
 | 
					 | 
				
			||||||
		Frame     Rectangle `json:"frame"`
 | 
					 | 
				
			||||||
	} `json:"photos"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Make(req Request, source fs.FS, output io.Writer) {
 | 
					func Make(req Request, source fs.FS, output io.Writer) error {
 | 
				
			||||||
	rec := image.Rect(0, 0, int(req.Aspect.Width), int(req.Aspect.Height))
 | 
						rec := image.Rect(0, 0, int(req.Aspect.Width), int(req.Aspect.Height))
 | 
				
			||||||
	canvas := image.NewRGBA64(rec)
 | 
						canvas := image.NewRGBA64(rec)
 | 
				
			||||||
	for photo := range req.Photos {
 | 
						for _, photo := range req.Photos {
 | 
				
			||||||
		fmt.Println(photo)
 | 
							img, err := GetImage(source, photo.ImageName)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							croppedImage, err := Crop(img, photo.Crop)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							destRect := FrameTranslate(req.Aspect, req.Dimension, photo.Frame).ToImgRect()
 | 
				
			||||||
 | 
							resizedImg := resize.Resize(uint(destRect.Dx()), uint(destRect.Dy()), croppedImage, resize.Lanczos3)
 | 
				
			||||||
 | 
							draw.Draw(canvas, destRect, resizedImg, image.Point{0, 0}, draw.Src)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var opt jpeg.Options
 | 
				
			||||||
 | 
						opt.Quality = 100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return jpeg.Encode(output, canvas, &opt)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func FrameTranslate(resolution Dimension, frameSize Dimension, frame Rectangle) Rectangle {
 | 
				
			||||||
 | 
						newX := func(oldX uint) uint {
 | 
				
			||||||
 | 
							return oldX * resolution.Width / frameSize.Width
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						newY := func(oldY uint) uint {
 | 
				
			||||||
 | 
							return oldY * resolution.Height / frameSize.Height
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return Rectangle{
 | 
				
			||||||
 | 
							Start: Point{newX(frame.Start.X), newY(frame.Start.Y)},
 | 
				
			||||||
 | 
							End:   Point{newX(frame.End.X), newY(frame.End.Y)},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Println(canvas)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type HasSubImage interface {
 | 
					type HasSubImage interface {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,12 +26,52 @@ func init() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestMake(t *testing.T) {
 | 
					func TestMake(t *testing.T) {
 | 
				
			||||||
	t.Log("Test was run")
 | 
						req := Request{
 | 
				
			||||||
	img1f, err := testDataFS.Open("img1.jpg")
 | 
							BackgroundImage: "",
 | 
				
			||||||
	if err != nil {
 | 
							Aspect: Dimension{
 | 
				
			||||||
		t.Fatalf("opening image failed %v", err)
 | 
								Width:  816 * 4,
 | 
				
			||||||
 | 
								Height: 528 * 4 * 2,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							Dimension: Dimension{
 | 
				
			||||||
 | 
								Width:  816,
 | 
				
			||||||
 | 
								Height: 528 * 2,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							Photos: []Photo{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ImageName: "img1.jpg",
 | 
				
			||||||
 | 
									Crop: Rectangle{
 | 
				
			||||||
 | 
										Start: Point{
 | 
				
			||||||
 | 
											X: 431,
 | 
				
			||||||
 | 
											Y: 697,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										End: Point{
 | 
				
			||||||
 | 
											X: 2514,
 | 
				
			||||||
 | 
											Y: 2047,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Frame: Rectangle{
 | 
				
			||||||
 | 
										Start: Point{
 | 
				
			||||||
 | 
											X: 0,
 | 
				
			||||||
 | 
											Y: 0,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										End: Point{
 | 
				
			||||||
 | 
											X: 816,
 | 
				
			||||||
 | 
											Y: 528,
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Printf("%#v\n", img1f)
 | 
						out, err := os.Create("./test_op.jpg")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("failed to create ouput image file %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = Make(req, testDataFS, out)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("failed to make collage %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestCrop(t *testing.T) {
 | 
					func TestCrop(t *testing.T) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user