Hi there, I am currently trying to create a GIF that repeats infinitely. But I get confused when I look at APIs under image::gif::Encoder. It seems it would only generate a GIF that repeat exact one time.
I know there's another gif crate which we can use and image crate actually use gif crate provides these functionalities. But what is the best way to make infinite repeat GIFs , ideally I would like having only image dependency for my crate ?
Thanks a lot!
Most browsers will loop a gif by default if no other control is given. All that is required is that the last frame also specifies a delay and then for many purposes that will be used as the delay to loop into the first frame again.
Actual loop control in gif is an application extension (still, widely supported). The very basics are implemented in the gif crate directly: https://docs.rs/gif/0.10.3/gif/enum.ExtensionData.html#variant.Repetitions Here is a web resource I found for the extension type that is use to achieve the exact loop control if you want to read more: http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
There is also no large cost (in terms of binary size and compile time) associated with depending on gif if you depend on image already. Since the goal of image is to provide a common interface please use gif for the specialized purposes.
Thanks for answering the question.
Most browsers will loop a gif by default if no other control is given.
Here's what I generated using image crate. It doesn't loop on my browser (P.S. I am using firefox 69.0)

However, these GIFs is able to repeat again and again. (This is from a screen recorder)

There is also no large cost (in terms of binary size and compile time) associated with depending on gif if you depend on image already. Since the goal of image is to provide a common interface please use gif for the specialized purposes.
Of course, that is the case. But I am concerning about depending on several different versions of gif crate, cause I am working hard to reduce the binary size as well. Although this is not the case for now, my explicitly dependency would be likely different from the image crate one in the future.
I am working hard to reduce the binary artifact size. So it would be ideal if I can handle this completely with image crate. Or at least, re-export the gif crate from image crate.
Most browsers will loop a gif by default if no other control is given.
Sorry but you are right, it doesn't. I overlooked the loop control extension in the sample that I used to make that claim.
So any instruction on how I could use image crate to do this ?
read more: http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
This gives me a change to do a dirty hack that modifying the file after the GIF encoder is dropped. But I think it would be helpful if we can control the loop extension directly from image crate because of the versioning issue I mentioned.
Especially most of the crate author using
crate-name = "^version"
to include dependency. And that is what I am concerning.
Thanks again!
image = "0.22"
gif = "*"
makes cargo select the same version of gif that's also used in image during version resolution. Not sure if that is a guarantee but almost certain. Re-exporting gif extends that the public API (and thus SemVer compatibility) of image to the whole of gif, making upgrades to gif without a major breaking release of image also impossible, instead of having a more stable, common interface.
Hmm, avoid breaking by a breaking change is the full point of using exact version instead of a wildcard.
So the problem remains to who would be break if gif is making breaking change, either image crate or image crate itself plus all image's downstream using features provided by gif crate that isn't exposed by image.
The solution using gif = "*" sounds good for me so far. I am still prefer to have API that controls the loop (and maybe other tweaks) within image::gif, as long as image::gif provides GIF functionalities.
And if you guys think it's good to expose some of the gif tweak to image::gif, I am more than happy to make a PR for that.
Now I come up with a solution which disable gif support for image and directly depends gif from my crate. It just works fine.
But I think another problem is, if I use gif directly, there's no need to use image::gif anyway.
Plus image::gif::Encoder isn't the same type as gif::Encoder, thus once people adopt their own dependency to gif crate. It seems there's no reason to use image::gif anymore.
So I am still thinking it would be better to support those tweaks directly to image::gif. Since once people need to use gif crate, there's no reason to use image::gif anyway. This makes image::gif module meaningless once people need some tweak.
@38 I'm personally in favor of having image::gif just re-export the gif crate. The reason that it doesn't right now is that there are some types and traits from the image crate that it wouldn't have access to. That may be changing though once we have a separate image-core crate.
Thanks @fintelia, it seems the best approach for me is to disable the image gif feature and manipulate gif with the gif crate.
Most helpful comment
@38 I'm personally in favor of having
image::gifjust re-export thegifcrate. The reason that it doesn't right now is that there are some types and traits from the image crate that it wouldn't have access to. That may be changing though once we have a separateimage-corecrate.