{"id":66,"date":"2010-01-10T10:43:27","date_gmt":"2010-01-10T10:43:27","guid":{"rendered":"http:\/\/blog.stratus.org.uk\/?page_id=66"},"modified":"2010-01-13T08:43:50","modified_gmt":"2010-01-13T08:43:50","slug":"dev-simple-batch-gif-animation-for-weather-forecast","status":"publish","type":"page","link":"https:\/\/blog.stratus.org.uk\/?page_id=66","title":{"rendered":"Simple batch GIF Animation for Weather Forecast"},"content":{"rendered":"<h2><strong>Overview<\/strong><\/h2>\n<p>In this post we\u2019ll discuss a simple method for producing an animated GIF from a collection of separate images, using the ImageMagic command line interface and then setting it as a batch job to run every day.<\/p>\n<h2><strong>Background<\/strong><\/h2>\n<p>A common need in representing static information on the web is to somehow show changes in state. In this case, it was a simple need to take a dozen or so static images showing dry and saturated adiabatic lapse rates.<\/p>\n<p>An example of which is shown below and is a snap shot for one hour at one physical location for atmospheric conditions. This changes from hour to hour so we want to animate this so the view can see how the conditions chnage during the day.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-67\" title=\"RASP sample\" src=\"http:\/\/blog.stratus.org.uk\/wp-content\/uploads\/2010\/01\/rasp.jpg\" alt=\"RASP sample\" width=\"320\" height=\"320\" srcset=\"https:\/\/blog.stratus.org.uk\/wp-content\/uploads\/2010\/01\/rasp.jpg 320w, https:\/\/blog.stratus.org.uk\/wp-content\/uploads\/2010\/01\/rasp-150x150.jpg 150w, https:\/\/blog.stratus.org.uk\/wp-content\/uploads\/2010\/01\/rasp-300x300.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><strong> <\/strong><\/p>\n<h2><strong>Pre-Requistites<\/strong><\/h2>\n<p>The rest of this article makes a few assumptions on the likely setup in use. These are:<\/p>\n<ol>\n<li>That the source image\/s are avaialble via a simple HTTP pull (i.e. not embedded in any other pages).<\/li>\n<li>That ImageMagick is available on the command line.<\/li>\n<li>That the UNIX shell script will be hosted somewhere (sorry Microsoft users).<\/li>\n<li>It is possible to schedule the script using a cron interface or similar.<\/li>\n<\/ol>\n<h2><strong>Method<\/strong><\/h2>\n<p>The process for doing this is fairly simple:<\/p>\n<ol>\n<li>Set things up<\/li>\n<li>Grab the images<\/li>\n<li>Merge the images and save the target image somewhere publicly visible.<\/li>\n<li>Set up a cron job<\/li>\n<\/ol>\n<p>Let\u2019s look at each stage.<\/p>\n<h3><strong>Step 1 \u2013 Set things up<br \/>\n<\/strong><\/h3>\n<p>Our script starts as a shell script and to save a lot of typing we set up some constants as follows:<\/p>\n<pre style=\"padding-left: 30px;\">#!\/bin\/sh\r\nTARGETDIR=\/home\/user\/somewhere\r\nHOMEDIR=\/home\/user\/cgi-bin\/skewt\r\nSRCURL='http:\/\/rasp.inn.leedsmet.ac.uk\/cgi-bin\/get_rasp_skewt.cgi?region=UK12&grid=d2&day=0&i=1332&k=1547&width=2000&height=2000&time'\r\nFILENAME=skewt-rat\r\n\r\n#Go to the location of the script\r\ncd $HOMEDIR\r\n\r\n#Remove any existing images\r\nrm -f $HOMEDIR\/$FILENAME*.gif<\/pre>\n<p>In which we set where we send the output to, where the script is, the location of the source images and an output filename prefix. Then we delete any existing temporary files (which we leave in case we need to look at them if the image fails).<\/p>\n<h3><strong>Step 2 \u2013 Grab The Images<\/strong><\/h3>\n<p>This can be tricky depending on your hosting supplier. If you have complete control, you can use <em>wget<\/em> but it has been found the <em>curl <\/em>will often be available if <em>wget <\/em>is not.<\/p>\n<p>Here we use<em> curl<\/em> and simply get the images one line at a time. To keep things simple, there is no error checking here. Hence, if the file is empty or the <em>curl<\/em> fails, then the image will probably have blank pages in it.<\/p>\n<pre style=\"padding-left: 30px;\"># do the main image first, but we don't overwrite the one that's there\r\ncurl $SRCURL=0600 > $HOMEDIR\/$FILENAME-0600.gif\r\ncurl $SRCURL=0700 > $HOMEDIR\/$FILENAME-0700.gif\r\ncurl $SRCURL=0800 > $HOMEDIR\/$FILENAME-0800.gif\r\ncurl $SRCURL=0900 > $HOMEDIR\/$FILENAME-0900.gif\r\ncurl $SRCURL=1000 > $HOMEDIR\/$FILENAME-1000.gif\r\ncurl $SRCURL=1100 > $HOMEDIR\/$FILENAME-1100.gif\r\ncurl $SRCURL=1200 > $HOMEDIR\/$FILENAME-1200.gif\r\ncurl $SRCURL=1300 > $HOMEDIR\/$FILENAME-1300.gif\r\ncurl $SRCURL=1400 > $HOMEDIR\/$FILENAME-1400.gif\r\ncurl $SRCURL=1500 > $HOMEDIR\/$FILENAME-1500.gif\r\ncurl $SRCURL=1600 > $HOMEDIR\/$FILENAME-1600.gif\r\ncurl $SRCURL=1700 > $HOMEDIR\/$FILENAME-1700.gif\r\ncurl $SRCURL=1800 > $HOMEDIR\/$FILENAME-1800.gif<\/pre>\n<p>It is possible to iterate a shell script loop to put the hour in, but to keep it simple the same command line is repeated.<\/p>\n<h3><strong>Step 3 \u2013 Merge The Images<\/strong><\/h3>\n<p>This is easily done using ImageMagick as shown below.<\/p>\n<pre style=\"padding-left: 30px;\"># Now create the animated GIF\r\nconvert -delay 100\u00a0 -size 800x800 \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-0600.gif -page +0+0 $HOMEDIR\/$FILENAME-0700.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-0800.gif -page +0+0 $HOMEDIR\/$FILENAME-0900.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1000.gif -page +0+0 $HOMEDIR\/$FILENAME-1100.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1200.gif -page +0+0 $HOMEDIR\/$FILENAME-1300.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1400.gif -page +0+0 $HOMEDIR\/$FILENAME-1500.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1600.gif -page +0+0 $HOMEDIR\/$FILENAME-1700.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1800.gif \\\r\n -loop 0\u00a0 $TARGETDIR\/$FILENAME.gif<\/pre>\n<p>The references below will give a breakdown of the options used, but put simply, we have one long command-line entry (split using back-slashes), which is 800\u00d7800 pixels, a one second delay between each image that loops forever. We also send the output to the target location.<\/p>\n<p>Easy.<\/p>\n<h3><strong>Step 4 \u2013 Automation<\/strong><\/h3>\n<p>If you have access to a <em>cron <\/em>or similar mechanism, making this a daily event is as easy as adding the following to the <em>crontab<\/em> file. Assuming the script file is called <em>pullskewt.sh<\/em> in the <em>cgi-bin\/skewt <\/em>folder of your hosted area, add this to run the job at 06:00 every day:<\/p>\n<pre style=\"padding-left: 30px;\">* \u00a0\u00a0\u00a0 \u00a06 \u00a0\u00a0\u00a0 \u00a0* \u00a0\u00a0\u00a0 \u00a0* \u00a0\u00a0\u00a0 \u00a0* \u00a0\u00a0\u00a0 \u00a0 cgi-bin\/skewt\/pullskewt.sh<\/pre>\n<p>The name \u201c<em>skewt<\/em>\u201d comes from the graph name used on the source. It can be anything you like.<\/p>\n<h2><strong>Useful References<\/strong><\/h2>\n<p>In terms of background information, the following are useful in explaining the detail of GIF animation and the use of ImageMagick:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.imagemagick.org\/Usage\/anim_basics\/\" target=\"_blank\">ImageMagick v6 Examples \u2013 Animation Basics<\/a><\/li>\n<li><a href=\"http:\/\/www.imagemagick.org\/script\/command-line-processing.php\" target=\"_blank\">ImageMagick Command Line Processing<\/a><\/li>\n<\/ul>\n<h2><strong>Final Script<\/strong><\/h2>\n<p>Now finished, your script should look like:<\/p>\n<pre style=\"padding-left: 30px;\">#!\/bin\/sh\r\nTARGETDIR=\/home\/user\/somewhere\r\nHOMEDIR=\/home\/user\/cgi-bin\/skewt\r\nSRCURL='http:\/\/rasp.inn.leedsmet.ac.uk\/cgi-bin\/get_rasp_skewt.cgi?region=UK12&grid=d2&day=0&i=1332&k=1547&width=2000&height=2000&time'\r\nFILENAME=skewt-rat\r\n\r\ncd $HOMEDIR\r\n\r\n#remove any existing images\r\nrm -f $HOMEDIR\/$FILENAME*.gif\r\n\r\n# do the main image first, but we don't overwrite the one that's there\r\ncurl $SRCURL=0600 > $HOMEDIR\/$FILENAME-0600.gif\r\ncurl $SRCURL=0700 > $HOMEDIR\/$FILENAME-0700.gif\r\ncurl $SRCURL=0800 > $HOMEDIR\/$FILENAME-0800.gif\r\ncurl $SRCURL=0900 > $HOMEDIR\/$FILENAME-0900.gif\r\ncurl $SRCURL=1000 > $HOMEDIR\/$FILENAME-1000.gif\r\ncurl $SRCURL=1100 > $HOMEDIR\/$FILENAME-1100.gif\r\ncurl $SRCURL=1200 > $HOMEDIR\/$FILENAME-1200.gif\r\ncurl $SRCURL=1300 > $HOMEDIR\/$FILENAME-1300.gif\r\ncurl $SRCURL=1400 > $HOMEDIR\/$FILENAME-1400.gif\r\ncurl $SRCURL=1500 > $HOMEDIR\/$FILENAME-1500.gif\r\ncurl $SRCURL=1600 > $HOMEDIR\/$FILENAME-1600.gif\r\ncurl $SRCURL=1700 > $HOMEDIR\/$FILENAME-1700.gif\r\ncurl $SRCURL=1800 > $HOMEDIR\/$FILENAME-1800.gif\r\n\r\n# Now create the animated GIF\r\nconvert -delay 100\u00a0 -size 800x800 \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-0600.gif -page +0+0 $HOMEDIR\/$FILENAME-0700.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-0800.gif -page +0+0 $HOMEDIR\/$FILENAME-0900.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1000.gif -page +0+0 $HOMEDIR\/$FILENAME-1100.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1200.gif -page +0+0 $HOMEDIR\/$FILENAME-1300.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1400.gif -page +0+0 $HOMEDIR\/$FILENAME-1500.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1600.gif -page +0+0 $HOMEDIR\/$FILENAME-1700.gif \\\r\n -page +0+0 $HOMEDIR\/$FILENAME-1800.gif \\\r\n -loop 0\u00a0 $TARGETDIR\/$FILENAME.gif<\/pre>\n<h2><strong>Example Image<\/strong><\/h2>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-74\" title=\"skewt-rat-animated\" src=\"http:\/\/blog.stratus.org.uk\/wp-content\/uploads\/2010\/01\/skewt-rat.gif\" alt=\"skewt-rat-animated\" width=\"320\" height=\"320\" srcset=\"https:\/\/blog.stratus.org.uk\/wp-content\/uploads\/2010\/01\/skewt-rat.gif 320w, https:\/\/blog.stratus.org.uk\/wp-content\/uploads\/2010\/01\/skewt-rat-150x150.gif 150w, https:\/\/blog.stratus.org.uk\/wp-content\/uploads\/2010\/01\/skewt-rat-300x300.gif 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><br \/>\n<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Overview In this post we\u2019ll discuss a simple method for producing an animated GIF from a collection of separate images, using the ImageMagic command line interface and then setting it as a batch job to run every day. Background A &hellip; <a href=\"https:\/\/blog.stratus.org.uk\/?page_id=66\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":84,"menu_order":0,"comment_status":"closed","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-66","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=\/wp\/v2\/pages\/66","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=66"}],"version-history":[{"count":19,"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=\/wp\/v2\/pages\/66\/revisions"}],"predecessor-version":[{"id":147,"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=\/wp\/v2\/pages\/66\/revisions\/147"}],"up":[{"embeddable":true,"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=\/wp\/v2\/pages\/84"}],"wp:attachment":[{"href":"https:\/\/blog.stratus.org.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=66"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}