diff --git a/images/encode.go b/images/encode.go new file mode 100644 index 000000000..a64e50d1a --- /dev/null +++ b/images/encode.go @@ -0,0 +1,38 @@ +package images + +import ( + "image" + "image/jpeg" + "io" + "os" +) + +func RenderAndMakeFile(img image.Image, imgDetail *Details) error { + out, err := os.Create(imgDetail.FileName) + if err != nil { + return err + } + defer out.Close() + + err = Render(out, img, imgDetail) + if err != nil { + return err + } + + fi, _ := out.Stat() + imgDetail.SizeFile = fi.Size() + + return nil +} + +func Render(w io.Writer, img image.Image, imgDetail *Details) error { + // Currently a wrapper for renderJpeg, but this function is useful if multiple render formats are needed + return renderJpeg(w, img, imgDetail) +} + +func renderJpeg(w io.Writer, m image.Image, imgDetail *Details) error { + o := new(jpeg.Options) + o.Quality = imgDetail.Quality + + return jpeg.Encode(w, m, o) +} diff --git a/images/encode_test.go b/images/encode_test.go new file mode 100644 index 000000000..bf3c40534 --- /dev/null +++ b/images/encode_test.go @@ -0,0 +1,94 @@ +package images + +import ( + "bytes" + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestRender(t *testing.T) { + cs := []struct { + FileName string + RenderSize int + }{ + { + "elephant.jpg", + 1447, + }, + { + "rose.webp", + 11119, + }, + { + "spin.gif", + 2263, + }, + { + "status.png", + 5834, + }, + } + options := Details{ + Quality: 70, + } + + for _, c := range cs { + img, err := Get(path + c.FileName) + require.NoError(t, err) + + bb := bytes.NewBuffer([]byte{}) + err = Render(bb, img, &options) + require.NoError(t, err) + + require.Exactly(t, c.RenderSize, bb.Len()) + } +} + +func TestMakeAndRenderFile(t *testing.T) { + cs := []struct { + FileName string + OutName string + OutputSize int64 + }{ + { + "elephant.jpg", + "_elephant.jpg", + 1447, + }, + { + "rose.webp", + "_rose.jpg", + 11119, + }, + { + "spin.gif", + "_spin.jpg", + 2263, + }, + { + "status.png", + "_status.jpg", + 5834, + }, + } + + for _, c := range cs { + img, err := Get(path + c.FileName) + require.NoError(t, err) + + options := &Details{ + FileName: path + c.OutName, + Quality: 70, + } + + err = RenderAndMakeFile(img, options) + require.NoError(t, err) + require.Exactly(t, c.OutputSize, options.SizeFile) + + // tidy up + err = os.Remove(options.FileName) + require.NoError(t, err) + } +}