imaging icon indicating copy to clipboard operation
imaging copied to clipboard

Can't make GIFs work properly

Open ivanjaros opened this issue 1 year ago • 2 comments

I am, unable to produce proper gifs, there are always artifacts or loss of visual quality, even if gif is encoded without errors. I saw examples here and am processing individual frames but the result is always garbage. Changing filters did not help either. Any idea why?

                        g, err := gif.DecodeAll(src)
			if err != nil {
				return err
			}

			if len(g.Image) == 0 {
				_, err := io.Copy(dst, src)
				return err
			}

			g.Config.Width = 0
			g.Config.Height = 0

			for k := range g.Image {
				for j := range rules {
					if result, ok := rules[j].Apply(g.Image[k], filter).(*image.NRGBA); ok {
						g.Image[k] = &image.Paletted{
							Pix:     result.Pix,
							Stride:  result.Stride,
							Rect:    result.Rect,
							Palette: g.Image[k].Palette,
						}
					}
				}
				if g.Image[k].Bounds().Max.X > g.Config.Width || g.Image[k].Bounds().Max.Y > g.Config.Height {
					g.Config.Width = g.Image[k].Bounds().Max.X
					g.Config.Height = g.Image[k].Bounds().Max.Y
				}
			}

			return gif.EncodeAll(dst, g)

I have just one resize rule for testing(called by the Apply).

The source is random gif from the internet with 800x600 dimensions and I am testing resizing to half.

Source: source

Result(also 3x in file size) dst

ivanjaros avatar Nov 09 '24 06:11 ivanjaros

Also, it seems that if the gif is larger(not sure when this triggers), i will get

panic: lzw: input byte too large for the litWidth

This is caused by something off with colors in the pallete after transformation, triggered in gif.encoder.writeImageBlock.

obrázok

obrázok

ivanjaros avatar Nov 09 '24 10:11 ivanjaros

This produces something:

        g, err := gif.DecodeAll(src)
	if err != nil {
		return err
	}

	g.Config.Height = 0
	g.Config.Width = 0

	for k := range g.Image {
		src := image.Image(g.Image[k])

		for j := range rules {
			src = rules[j].Apply(src, filter)
		}

		tmp := image.NewPaletted(src.Bounds(), g.Image[k].Palette)
		draw.Draw(tmp, src.Bounds(), src, image.Point{}, draw.Src)
		g.Image[k] = tmp

		// find the largest image in the set(should be the first one)
		if tmp.Bounds().Max.X > g.Config.Width || tmp.Bounds().Max.Y > g.Config.Height {
			g.Config.Width = tmp.Bounds().Max.X
			g.Config.Height = tmp.Bounds().Max.Y
		}
	}

	return gif.EncodeAll(dst, g)

But it is inconsistent. The following are three random gifs from the internet. The first one is most problematic. It's like there are two gifs within one(it's weird and I cannot make it work properly with this one), second one is losing color information and produces artifacts. Third one is totally fine.

dst

dst2

dst3

ivanjaros avatar Nov 09 '24 11:11 ivanjaros