You've already forked collage-maker
							
							add crop and few helpers
This commit is contained in:
		@@ -2,6 +2,9 @@
 | 
			
		||||
package collage
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
)
 | 
			
		||||
@@ -21,6 +24,13 @@ type Rectangle struct {
 | 
			
		||||
	End   Point `json:"end"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r Rectangle) ToImgRect() image.Rectangle {
 | 
			
		||||
	return image.Rectangle{
 | 
			
		||||
		Min: image.Point{int(r.Start.X), int(r.Start.Y)},
 | 
			
		||||
		Max: image.Point{int(r.End.X), int(r.End.Y)},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Request struct {
 | 
			
		||||
	BackgroundImage string    `json:"background_image"`
 | 
			
		||||
	Aspect          Dimension `json:"aspect"`
 | 
			
		||||
@@ -32,5 +42,31 @@ type Request struct {
 | 
			
		||||
	} `json:"photos"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Make(request Request, source fs.FS, output io.Writer) {
 | 
			
		||||
func Make(req Request, source fs.FS, output io.Writer) {
 | 
			
		||||
	rec := image.Rect(0, 0, int(req.Aspect.Width), int(req.Aspect.Height))
 | 
			
		||||
	canvas := image.NewRGBA64(rec)
 | 
			
		||||
	for photo := range req.Photos {
 | 
			
		||||
		fmt.Println(photo)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println(canvas)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type HasSubImage interface {
 | 
			
		||||
	SubImage(r image.Rectangle) image.Image
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Crop(img image.Image, r Rectangle) (image.Image, error) {
 | 
			
		||||
	if imgHS, ok := img.(HasSubImage); ok {
 | 
			
		||||
		return imgHS.SubImage(r.ToImgRect()), nil
 | 
			
		||||
	}
 | 
			
		||||
	return nil, errors.New("image does not support cropping")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetImage(source fs.FS, imageName string) (image.Image, error) {
 | 
			
		||||
	imgF, err := source.Open(imageName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	img, _, err := image.Decode(imgF)
 | 
			
		||||
	return img, err
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,22 +3,95 @@ package collage
 | 
			
		||||
import (
 | 
			
		||||
	"embed"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image"
 | 
			
		||||
	"image/jpeg"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:embed test_data/*
 | 
			
		||||
var testData embed.FS
 | 
			
		||||
 | 
			
		||||
var testDataFS fs.FS
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	var err error
 | 
			
		||||
	testDataFS, err = fs.Sub(testData, "test_data")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Panicf("getting test_data subdir failed %v", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestMake(t *testing.T) {
 | 
			
		||||
	t.Log("Test was run")
 | 
			
		||||
	ifs, err := fs.Sub(testData, "test_data")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("getting test_data subdir failed %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	img1f, err := ifs.Open("img1.jpg")
 | 
			
		||||
	img1f, err := testDataFS.Open("img1.jpg")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("opening image failed %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Printf("%#v\n", img1f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCrop(t *testing.T) {
 | 
			
		||||
	img, err := GetImage(testDataFS, "img1.jpg")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("failed to get image %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	r := Rectangle{
 | 
			
		||||
		Start: Point{X: 431, Y: 697},
 | 
			
		||||
		End:   Point{X: 2514, Y: 2047},
 | 
			
		||||
	}
 | 
			
		||||
	cropped, err := Crop(img, r)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("failed to crop image %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	croppedImgPrefix := fmt.Sprint(cropped)[:1000]
 | 
			
		||||
 | 
			
		||||
	refPrefixf, err := testDataFS.Open("cropped_image_prefix.txt")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("failed to open ref prefix %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	refImgPrefix, err := io.ReadAll(refPrefixf)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("failed to read ref prefix %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if string(refImgPrefix) != croppedImgPrefix {
 | 
			
		||||
		t.Fatalf("Cropped image is not the same as reference image")
 | 
			
		||||
	}
 | 
			
		||||
	// SavePrefix(cropped)
 | 
			
		||||
	// expectedImage, err := GetImage(testDataFS, "test_output.jpg")
 | 
			
		||||
	// if err != nil {
 | 
			
		||||
	// 	t.Fatalf("failed to get reference crop image %v", err)
 | 
			
		||||
	// }
 | 
			
		||||
	// fmt.Printf("%v\n", cropped)
 | 
			
		||||
	// fmt.Printf("%v\n", expectedImage)
 | 
			
		||||
	// if fmt.Sprintf("%#v", cropped) != fmt.Sprintf("%#v", expectedImage) {
 | 
			
		||||
	// 	t.Fatalf("Cropped image is not the same as reference image")
 | 
			
		||||
	// }
 | 
			
		||||
	// SaveImage(cropped)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Save first 1000 bytes of string representation to compare against reference
 | 
			
		||||
func SavePrefix(img image.Image) error {
 | 
			
		||||
	imgStr := fmt.Sprint(img)
 | 
			
		||||
	prefix := imgStr[:1000]
 | 
			
		||||
	return os.WriteFile("./test_data_prefix.txt", []byte(prefix), 0644)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SaveImage(img image.Image) {
 | 
			
		||||
	out, err := os.Create("./test_output.jpg")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var opt jpeg.Options
 | 
			
		||||
	opt.Quality = 100
 | 
			
		||||
 | 
			
		||||
	jpeg.Encode(out, img, &opt)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user