deanm / omggif

JavaScript implementation of a GIF 89a encoder and decoder
706 stars 79 forks source link

Weird artifacts in some GIF frames #46

Open sayhicoelho opened 22 hours ago

sayhicoelho commented 22 hours ago

Reproduce

Open: https://movableink.github.io/gif-inspector/ and load the GIFs below:

GIF 1 GIF 2 GIF 3
waiting funny-dog 70cb0de7-982a-48fa-97a2-762011c5ff15

Result example

image

Example code in React (web)

import { useRef } from 'react';
import { GifReader } from 'omggif';

export default function App() {
  const outputRef = useRef()

  async function loadGifFrameList(blob) {
    const arrayBuffer = await blob.arrayBuffer();
    const intArray = new Uint8Array(arrayBuffer);

    const reader = new GifReader(intArray);

    const info = reader.frameInfo(0);

    return new Array(reader.numFrames()).fill(0).map((_, k) => {
      const image = new ImageData(info.width, info.height);

      reader.decodeAndBlitFrameRGBA(k, image.data);

      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')

      canvas.width = info.width
      canvas.height = info.height

      ctx.putImageData(image, 0, 0)

      return canvas;
    });
  };

  async function onChange(e) {
    const file = e.target.files[0]
    const frames = await loadGifFrameList(file)
    outputRef.current.innerHTML = ''

    for (const canvas of frames) {
      outputRef.current.appendChild(canvas)
    }
  }

  return (
    <div className="App">
      <input onChange={onChange} type="file" />
      <div ref={outputRef} />
    </div>
  );
}

How can I fix these artifacts?

PS: If you open these GIFs in another application like Photoshop, you'll see all the frames without artifacts.

lhm0 commented 20 hours ago

Your example is very nice:

frame0 is a full image. The subsequent frames are incremental and only show the changes. In order to get a full image, you need to draw frame1 "on top of" frame0, and so on.