Skip to content

Commit

Permalink
improve gif thumbnail generation
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas committed Mar 11, 2022
1 parent 46643b0 commit a01cd1f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 8 deletions.
5 changes: 5 additions & 0 deletions changelog/unreleased/gif-thumbnails.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Bugfix: Improve gif thumbnails

Improved the gif thumbnail generation for gifs with different disposal strategies.

https://github.com/owncloud/ocis/pull/3305
39 changes: 31 additions & 8 deletions thumbnails/pkg/thumbnail/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package thumbnail
import (
"errors"
"image"
"image/color"
"image/draw"
"image/gif"
"strings"
Expand Down Expand Up @@ -35,22 +36,44 @@ func (g SimpleGenerator) GenerateThumbnail(size image.Rectangle, img interface{}
type GifGenerator struct{}

func (g GifGenerator) GenerateThumbnail(size image.Rectangle, img interface{}) (interface{}, error) {
// Code inspired by https://github.com/willnorris/gifresize/blob/db93a7e1dcb1c279f7eeb99cc6d90b9e2e23e871/gifresize.go

m, ok := img.(*gif.GIF)
if !ok {
return nil, ErrInvalidType2
}
var bounds image.Rectangle
for i := range m.Image {
img := imaging.Resize(m.Image[i], size.Dx(), size.Dy(), imaging.Lanczos)
bounds = image.Rect(0, 0, size.Dx(), size.Dy())
m.Image[i] = image.NewPaletted(bounds, m.Image[i].Palette)
draw.Draw(m.Image[i], bounds, img, image.Pt(0, 0), draw.Src)
// Create a new RGBA image to hold the incremental frames.
srcX, srcY := m.Config.Width, m.Config.Height
b := image.Rect(0, 0, srcX, srcY)
tmp := image.NewRGBA(b)

for i, frame := range m.Image {
bounds := frame.Bounds()
prev := tmp
draw.Draw(tmp, bounds, frame, bounds.Min, draw.Over)
scaled := imaging.Resize(tmp, size.Dx(), size.Dy(), imaging.Lanczos)
m.Image[i] = g.imageToPaletted(scaled, frame.Palette)

switch m.Disposal[i] {
case gif.DisposalBackground:
tmp = image.NewRGBA(b)
case gif.DisposalPrevious:
tmp = prev
}
}
m.Config.Height = bounds.Dy()
m.Config.Width = bounds.Dx()
m.Config.Width = size.Dx()
m.Config.Height = size.Dy()

return m, nil
}

func (g GifGenerator) imageToPaletted(img image.Image, p color.Palette) *image.Paletted {
b := img.Bounds()
pm := image.NewPaletted(b, p)
draw.FloydSteinberg.Draw(pm, b, img, image.Point{})
return pm
}

// GeneratorForType returns the generator for a given file type
// or nil if the type is not supported.
func GeneratorForType(fileType string) (Generator, error) {
Expand Down

0 comments on commit a01cd1f

Please sign in to comment.