add Make collage

This commit is contained in:
Balakrishnan Balasubramanian 2023-08-11 23:20:53 -04:00
parent 846e191582
commit b298cb019d
2 changed files with 87 additions and 15 deletions

View File

@ -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 {

View File

@ -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) {