{"id":5473,"date":"2022-03-23T16:12:40","date_gmt":"2022-03-23T20:12:40","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=5473"},"modified":"2022-03-24T07:09:45","modified_gmt":"2022-03-24T11:09:45","slug":"puzzles-about-gif-delaytime","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2022\/03\/23\/puzzles-about-gif-delaytime\/","title":{"rendered":"Puzzles About GIF DelayTime"},"content":{"rendered":"<div class = rtcContent><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span><\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>[TLDR: To create a fast GIF animation using <\/span><span style=' font-family: monospace;'>imwrite<\/span><span>, use a <\/span><span style=' font-family: monospace;'>DelayTime<\/span><span> of 0.02 instead of 0.]<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>In my <\/span><a href = \"https:\/\/blogs.mathworks.com\/steve\/2022\/02\/28\/a-short-game-of-life\/\"><span>28-Feb-2022 post<\/span><\/a><span>, I showed some code that created an animated GIF file using a DelayTime of 0.<\/span><\/div><div class = 'preformatted-matlab' style = 'margin: 10px 3px 10px 55px; padding: 10px 10px 10px 5px; '><div  style = 'border-left: 0px none rgb(33, 33, 33); border-right: 0px none rgb(33, 33, 33); border-top: 0px none rgb(33, 33, 33); border-bottom: 0px none rgb(33, 33, 33); border-radius: 0px; padding: 0px; line-height: 15.6px; min-height: 16px; white-space: pre; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; font-size: 12px; '><span style=\"white-space: pre\"><span >im = rand(750,750)&gt;0.8;<\/span><\/span><\/div><div  style = 'border-left: 0px none rgb(33, 33, 33); border-right: 0px none rgb(33, 33, 33); border-top: 0px none rgb(33, 33, 33); border-bottom: 0px none rgb(33, 33, 33); border-radius: 0px; padding: 0px; line-height: 15.6px; min-height: 16px; white-space: pre; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; font-size: 12px; '><span style=\"white-space: pre\"><span style=\"color: rgb(14, 0, 255);\">for <\/span><span >k=1:500<\/span><\/span><\/div><div  style = 'border-left: 0px none rgb(33, 33, 33); border-right: 0px none rgb(33, 33, 33); border-top: 0px none rgb(33, 33, 33); border-bottom: 0px none rgb(33, 33, 33); border-radius: 0px; padding: 0px; line-height: 15.6px; min-height: 16px; white-space: pre; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; font-size: 12px; '><span style=\"white-space: pre\"><span >  t = conv2(im(:,:,k),[2,2,2;2,1,2;2,2,2],<\/span><span style=\"color: rgb(167, 9, 245);\">'same'<\/span><span >);<\/span><\/span><\/div><div  style = 'border-left: 0px none rgb(33, 33, 33); border-right: 0px none rgb(33, 33, 33); border-top: 0px none rgb(33, 33, 33); border-bottom: 0px none rgb(33, 33, 33); border-radius: 0px; padding: 0px; line-height: 15.6px; min-height: 16px; white-space: pre; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; font-size: 12px; '><span style=\"white-space: pre\"><span >  im(:,:,1,k+1) = (t &gt; 4) &amp; (t &lt; 8);<\/span><\/span><\/div><div  style = 'border-left: 0px none rgb(33, 33, 33); border-right: 0px none rgb(33, 33, 33); border-top: 0px none rgb(33, 33, 33); border-bottom: 0px none rgb(33, 33, 33); border-radius: 0px; padding: 0px; line-height: 15.6px; min-height: 16px; white-space: pre; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; font-size: 12px; '><span style=\"white-space: pre\"><span style=\"color: rgb(14, 0, 255);\">end<\/span><\/span><\/div><div  style = 'border-left: 0px none rgb(33, 33, 33); border-right: 0px none rgb(33, 33, 33); border-top: 0px none rgb(33, 33, 33); border-bottom: 0px none rgb(33, 33, 33); border-radius: 0px; padding: 0px; line-height: 15.6px; min-height: 16px; white-space: pre; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; font-size: 12px; '><span style=\"white-space: pre\"><span >imwrite(~im,<\/span><span style=\"color: rgb(167, 9, 245);\">'life.gif'<\/span><span >,<\/span><span style=\"color: rgb(167, 9, 245);\">'DelayTime'<\/span><span >,0,<\/span><span style=\"color: rgb(167, 9, 245);\">'LoopCount'<\/span><span >,1)<\/span><\/span><\/div><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>In response, reader Mikhail commented that one shouldn't use a <\/span><span style=' font-family: monospace;'>DelayTime<\/span><span> of 0 for the purpose of creating fast GIF animations. He pointed me to an blog post by Ben Phelps called <\/span><a href = \"https:\/\/www.biphelps.com\/blog\/The-Fastest-GIF-Does-Not-Exist\"><span>\"The Fastest GIF Does Not Exist.\"<\/span><\/a><span> <\/span><span style=' font-style: italic;'>(Note: If you visit this site, you may get a security warning in your browser. Apparently, the site's certificate expired a few days ago. Visit at your own risk. I have attempted to contact the author to let them know.)<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>Many years ago (about 25!), I used to work on image file format support in MATLAB, so I usually start investigating such questions by looking at the specification for the format in question. The relevant spec is <\/span><a href = \"https:\/\/www.w3.org\/Graphics\/GIF\/spec-gif89a.txt\"><span>GIF89a<\/span><\/a><span>, and here's the key paragraph:<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><img class = \"imageNode\" src = \"https:\/\/blogs.mathworks.com\/steve\/files\/gif_delay_time_1.png\" width = \"587\" height = \"105\" alt = \"\" style = \"vertical-align: baseline; width: 587px; height: 105px;\"><\/img><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>Notice that this language doesn't specify exactly what is supposed to happen if the Delay Time is 0.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>One thing I've learned by experience is that the actual behavior of commonly used software applications sometimes varies from the spec, and implementers must pay attention to that. Ben has looked at the publicly available source code for several browsers and other applications and discovered a Delay Time of 0 or 1 (1\/100 s) is generally not honored. Instead, for various practical and historical reasons, a very low Delay Time like 0 or 1 is often bumped up arbitrarily to a value of 10 (1\/10 s).<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>Therefore, setting Delay Time to 0 is not going to give you the fastest possible animation! I tested this in Safari, the browser I use on my Mac, and this does appear to be true.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>This GIF was generated using <\/span><span style=' font-family: monospace;'>DelayTime<\/span><span> of 0:<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><img class = \"imageNode\" src = \"https:\/\/blogs.mathworks.com\/steve\/files\/gif_delay_time_2.gif\" width = \"500\" height = \"500\" alt = \"life (delay time = 0).gif\" style = \"vertical-align: baseline; width: 500px; height: 500px;\"><\/img><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span><\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>This one was generated using a <\/span><span style=' font-family: monospace;'>DelayTime<\/span><span> of 0.02 (<\/span><span style=' font-family: monospace;'>imwrite<\/span><span> uses seconds instead of hundredths of seconds for this parameter):<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><img class = \"imageNode\" src = \"https:\/\/blogs.mathworks.com\/steve\/files\/gif_delay_time_3.gif\" width = \"500\" height = \"500\" alt = \"life (delay time = 0.02).gif\" style = \"vertical-align: baseline; width: 500px; height: 500px;\"><\/img><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span><\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>Indeed, the second version does animate much more quickly.<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>One implication is that we may need to change the <\/span><span style=' font-family: monospace;'>imwrite<\/span><span> documentation, which specifically says to use <\/span><span style=' font-family: monospace;'>DelayTime<\/span><span> of 0 to get the fastest animation:<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><img class = \"imageNode\" src = \"https:\/\/blogs.mathworks.com\/steve\/files\/gif_delay_time_4.png\" width = \"639\" height = \"231\" alt = \"\" style = \"vertical-align: baseline; width: 639px; height: 231px;\"><\/img><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span><\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>I actually think it may be time to change the <\/span><span style=' font-family: monospace;'>imwrite<\/span><span> interface. Perhaps we could give this parameter a name, such as <\/span><span style=' font-family: monospace;'>FrameRate<\/span><span>, (in frames per second) and document a maximum value of 50 (which corresponds to a <\/span><span style=' font-family: monospace;'>DelayTime<\/span><span> of 0.02 s (or 2 hundredths of a second).<\/span><\/div><div  style = 'margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; '><span>I will make both suggestions to the development team responsible for <\/span><span style=' font-family: monospace;'>imwrite<\/span><span>.<\/span><\/div>\r\n<\/div><script type=\"text\/javascript\">var css = ''; var head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'); head.appendChild(style); style.type = 'text\/css'; if (style.styleSheet){ style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); }<\/script><a href=\"https:\/\/blogs.mathworks.com\/steve\/files\/gif_delay_time.mlx\"><button class=\"btn btn-sm btn_color_blue pull-right add_margin_10\">Download Live Script<\/button><\/a>","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/gif_delay_time_1.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>[TLDR: To create a fast GIF animation using imwrite, use a DelayTime of 0.02 instead of 0.]In my 28-Feb-2022 post, I showed some code that created an animated GIF file using a DelayTime of 0.im =... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2022\/03\/23\/puzzles-about-gif-delaytime\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":5458,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/5473"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=5473"}],"version-history":[{"count":2,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/5473\/revisions"}],"predecessor-version":[{"id":5479,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/5473\/revisions\/5479"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/5458"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=5473"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=5473"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=5473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}