diff --git a/third_party/gifresize/gifresize.go b/third_party/gifresize/gifresize.go new file mode 100644 index 0000000..405cfae --- /dev/null +++ b/third_party/gifresize/gifresize.go @@ -0,0 +1,86 @@ +// Copyright 2013 Daniel Pupius. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +// This demonstrates a solution to resizing animated gifs. +// +// Frames in an animated gif aren't necessarily the same size, subsequent +// frames are overlayed on previous frames. Therefore, resizing the frames +// individually may cause problems due to aliasing of transparent pixels. This +// example tries to avoid this by building frames from all previous frames and +// resizing the frames as RGB. + +import ( + "image" + "image/color/palette" + "image/draw" + "image/gif" + "log" + "os" + + "github.com/nfnt/resize" +) + +func main() { + process("shapes") + process("blob") +} + +func process(filename string) { + + // Open image file. + f, err := os.Open(filename + ".gif") + if err != nil { + log.Fatal(err.Error()) + } + defer f.Close() + + // Decode the original gif. + im, err := gif.DecodeAll(f) + if err != nil { + log.Fatal(err.Error()) + } + + // Create a new RGBA image to hold the incremental frames. + firstFrame := im.Image[0].Bounds() + b := image.Rect(0, 0, firstFrame.Dx(), firstFrame.Dy()) + img := image.NewRGBA(b) + + // Resize each frame. + for index, frame := range im.Image { + bounds := frame.Bounds() + draw.Draw(img, bounds, frame, bounds.Min, draw.Over) + im.Image[index] = ImageToPaletted(ProcessImage(img)) + } + + // Write resized gif. + out, err := os.Create(filename + ".out.fixed.gif") + if err != nil { + log.Fatal(err.Error()) + } + defer out.Close() + gif.EncodeAll(out, im) +} + +func ProcessImage(img image.Image) image.Image { + return resize.Resize(250, 0, img, resize.NearestNeighbor) +} + +func ImageToPaletted(img image.Image) *image.Paletted { + b := img.Bounds() + pm := image.NewPaletted(b, palette.Plan9) + draw.FloydSteinberg.Draw(pm, b, img, image.ZP) + return pm +}