improve gif thumbnail generation
This commit is contained in:
@@ -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
|
||||||
@@ -3,6 +3,7 @@ package thumbnail
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
"image/gif"
|
"image/gif"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -35,22 +36,44 @@ func (g SimpleGenerator) GenerateThumbnail(size image.Rectangle, img interface{}
|
|||||||
type GifGenerator struct{}
|
type GifGenerator struct{}
|
||||||
|
|
||||||
func (g GifGenerator) GenerateThumbnail(size image.Rectangle, img interface{}) (interface{}, error) {
|
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)
|
m, ok := img.(*gif.GIF)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrInvalidType2
|
return nil, ErrInvalidType2
|
||||||
}
|
}
|
||||||
var bounds image.Rectangle
|
// Create a new RGBA image to hold the incremental frames.
|
||||||
for i := range m.Image {
|
srcX, srcY := m.Config.Width, m.Config.Height
|
||||||
img := imaging.Resize(m.Image[i], size.Dx(), size.Dy(), imaging.Lanczos)
|
b := image.Rect(0, 0, srcX, srcY)
|
||||||
bounds = image.Rect(0, 0, size.Dx(), size.Dy())
|
tmp := image.NewRGBA(b)
|
||||||
m.Image[i] = image.NewPaletted(bounds, m.Image[i].Palette)
|
|
||||||
draw.Draw(m.Image[i], bounds, img, image.Pt(0, 0), draw.Src)
|
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 = size.Dx()
|
||||||
m.Config.Width = bounds.Dx()
|
m.Config.Height = size.Dy()
|
||||||
|
|
||||||
return m, nil
|
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
|
// GeneratorForType returns the generator for a given file type
|
||||||
// or nil if the type is not supported.
|
// or nil if the type is not supported.
|
||||||
func GeneratorForType(fileType string) (Generator, error) {
|
func GeneratorForType(fileType string) (Generator, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user