From fb5d8a6b3df960b60e876fd92b3f1505dd790bcc Mon Sep 17 00:00:00 2001 From: Rohan Singh Date: Fri, 18 Sep 2020 09:46:30 -0400 Subject: [PATCH] Add documentation and tests for animation --- Makefile | 2 +- README.md | 60 ++++++++++++++++++++++++++++++++++++++-- webp/anim_encode.go | 2 ++ webp/anim_encode_test.go | 51 ++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 webp/anim_encode_test.go diff --git a/Makefile b/Makefile index 6290749..3b895cb 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ $(libwebp_so): && wget http://downloads.webmproject.org/releases/webp/libwebp-$(LIBWEBP_VERSION).tar.gz \ && tar xf libwebp-$(LIBWEBP_VERSION).tar.gz \ && cd libwebp-$(LIBWEBP_VERSION) \ - && ./configure --prefix=$(LIBWEBP_PREFIX) \ + && ./configure --prefix=$(LIBWEBP_PREFIX) --enable-libwebpmux \ && make \ && make install diff --git a/README.md b/README.md index bb7744c..eaafe5f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A implementation of Go binding for [libwebp](https://developers.google.com/speed ## Dependencies -- libwebp 0.4, 0.5 +- libwebp 0.4, 0.5+, compiled with `--enable-libwebpmux` ## Usage @@ -76,10 +76,66 @@ func main() { } ``` + +### Encoding animations from a series of frames + +``` +package main + +import ( + "image" + "time" + + "github.com/harukasan/go-libwebp/test/util" + "github.com/harukasan/go-libwebp/webp" +) + +func main() { + // Get some frames + img := []image.Image{ + util.ReadPNG("butterfly.png"), + util.ReadPNG("checkerboard.png"), + util.ReadPNG("yellow-rose-3.png"), + } + + // Initialize the animation encoder + width, height := 24, 24 + anim, err := webp.NewAnimationEncoder(width, height, 0, 0) + if err != nil { + panic(err) + } + defer anim.Close() + + // Add each frame to the animation + for i, im := range img { + // all frames of an animation must have the same dimensions + cropped := im.(interface { + SubImage(r image.Rectangle) image.Image + }).SubImage(image.Rect(0, 0, width, height)) + + if err := anim.AddFrame(cropped, 100*time.Millisecond); err != nil { + panic(err) + } + } + + // Assemble the final animation + buf, err := anim.Assemble() + if err != nil { + panic(err) + } + + // Write to disk + f := util.CreateFile("animation.webp") + defer f.Close() + f.Write(buf) +} + +``` + ## TODO - Incremental decoding API -- Container API (Animation) +- Animation decoding ## License diff --git a/webp/anim_encode.go b/webp/anim_encode.go index 9e50c4f..cc5e2c9 100644 --- a/webp/anim_encode.go +++ b/webp/anim_encode.go @@ -1,6 +1,8 @@ package webp /* +#cgo LDFLAGS: -lwebpmux + #include #include #include diff --git a/webp/anim_encode_test.go b/webp/anim_encode_test.go new file mode 100644 index 0000000..0c1175d --- /dev/null +++ b/webp/anim_encode_test.go @@ -0,0 +1,51 @@ +package webp_test + +import ( + "image" + "testing" + "time" + + "github.com/harukasan/go-libwebp/test/util" + "github.com/harukasan/go-libwebp/webp" +) + +func TestEncodeAnimation(t *testing.T) { + data := util.ReadFile("cosmos.webp") + aWebP, err := webp.DecodeRGBA(data, &webp.DecoderOptions{}) + if err != nil { + t.Fatalf("Got Error: %v", err) + } + + img := []image.Image{ + util.ReadPNG("butterfly.png"), + util.ReadPNG("checkerboard.png"), + util.ReadPNG("yellow-rose-3.png"), + aWebP, + } + + width, height := 24, 24 + anim, err := webp.NewAnimationEncoder(width, height, 0, 0) + if err != nil { + t.Fatalf("initializing decoder: %v", err) + } + defer anim.Close() + + for i, im := range img { + // all frames of an animation must have the same dimensions + cropped := im.(interface { + SubImage(r image.Rectangle) image.Image + }).SubImage(image.Rect(0, 0, width, height)) + + if err := anim.AddFrame(cropped, 100*time.Millisecond); err != nil { + t.Errorf("adding frame %d: %v", i, err) + } + } + + buf, err := anim.Assemble() + if err != nil { + t.Fatalf("assembling animation: %v", err) + } + if len(buf) == 0 { + t.Errorf("assembled animation is empty") + } +}