Skip to content

example browser script#31

Open
mnutt wants to merge 3 commits intodeanm:masterfrom
movableink:example-web
Open

example browser script#31
mnutt wants to merge 3 commits intodeanm:masterfrom
movableink:example-web

Conversation

@mnutt
Copy link
Copy Markdown

@mnutt mnutt commented Jan 5, 2019

This library works great but there were a few gotchas in using it to render gifs on the web with canvas and support most gif files. I thought this example might be useful for people trying to use omggif in a web context.

@mnutt
Copy link
Copy Markdown
Author

mnutt commented Jan 5, 2019

(it's pretty much just the player extracted from https://movableink.github.io/gif-inspector/)

@mnutt mnutt closed this Feb 25, 2019
@deanm
Copy link
Copy Markdown
Owner

deanm commented Apr 10, 2019

Sorry for the delay, did you close it because it sat for too long or another reason? Thanks!

@mnutt mnutt reopened this Apr 10, 2019
Copy link
Copy Markdown
Owner

@deanm deanm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! Looks pretty good, a few things I probably need to check (there have been some recent github issues about how looping/disposal/etc works, and it has been years so I don't actually remember anymore)

Comment thread example_web/index.html Outdated
Comment thread example_web/index.html Outdated
} else if (previousFrameInfo && previousFrameInfo.disposal === 2) {
// disposal was "restore to background" which is essentially
// "restore to transparent"
context.clearRect(previousFrameInfo.x,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been a long time, I would have to refresh myself on all of the disposal stuff again, but I am pretty sure to do it properly you need to be able to fill with a background colour and stuff like that. I know that my plask example didn't do this either, maybe this is a chance for me to refresh myself on the details again...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there were a number of disposal methods in my original code that weren't quite right but should be fixed now. For background disposal, in practice all browsers dispose to transparent so I did that here as well.

Comment thread example_web/index.html Outdated

// get ready to draw next frame
previousFrameInfo = frameInfo;
frameNumber = (frameNumber + 1) % reader.numFrames();
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do this modulus and not just frameNumber === reader.numFrames() below?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've rearranged it to use frameNumber === reader.numFrames()

Comment thread example_web/index.html Outdated
frameNumber = (frameNumber + 1) % reader.numFrames();

if (frameNumber === reader.numFrames() - 1) {
if (--loops === 0) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could just be if (frameNumber === reader.numFrames()) { frameNumber = 0; ... }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that makes it a lot clearer.

Comment thread example_web/index.html Outdated
}
}

timeout = setTimeout(draw, frameInfo.delay * 10);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically (although I am not exactly sure how the timers work), you would probably actually want to set the timer before doing the decode and blit. The reason is otherwise the time spent in decode/blit is skewing your timer back every frame.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've done so and I believe it makes the timer more precise.

@mnutt
Copy link
Copy Markdown
Author

mnutt commented Jul 8, 2019

@deanm thanks for the review, there were definitely some edge cases that this wasn't catching. I think I've addressed them all now.

@mathieucaroff
Copy link
Copy Markdown

@deanm ping
Is there anything blocking the progress of the pull request?

@mathieucaroff
Copy link
Copy Markdown

https://stackoverflow.com/questions/60691364/extract-frames-from-gif-using-a-light-browser-js-libary-like-omggif

import { GifReader } from 'omggif';

export const loadGifFrameList = async (
    gifUrl: string,
): Promise<ImageData[]> => {
    const response = await fetch(gifUrl);
    const blob = await response.blob();
    const arrayBuffer = await blob.arrayBuffer();
    const intArray = new Uint8Array(arrayBuffer);

    const reader = new GifReader(intArray as Buffer);

    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 as any);

        return image;
    });
};

Comment thread example_web/index.html
// save this frame in case we need to revert to it later
previousImageData = context.getImageData(0, 0, reader.width, reader.height);
previousImageData.frame = frameNumber;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should there be an else that makes previousImageData = null ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, see https://github.com/deanm/omggif/pull/31/files/6b64106d7f5f3abd71b9166d166aa08e395b487e#diff-3ade314beb37a2490a4953585acfed048cef729832de94350bce3085be9f3e0aR73-R74 -- even if this frame doesn't get saved for later reversion, a future frame may use "restore to previous" and want to revert to the most recent saved frame.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This library and example are incredibly helpful. Thank you @mnutt and @deanm

@kelleyg2
Copy link
Copy Markdown

kelleyg2 commented Feb 2, 2024

Highly appreciated

@ADNANALISALHADABY
Copy link
Copy Markdown

Ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants