As of the recent Animated GIF Slide Extraction Primer Tutorial‘s progress with an Extraction of a User Nominated Animated GIF Slide web application’s …
- input animated GIF URL modus operandi … today we add …
- local operating system file browsing method of user animated GIF entry
… approach to our web application’s functionality abilities in a changed second draft extract_ag_slide_huh_of.html Animated GIF Slide Extraction web application (or Animated GIF Slide Extraction via User Interaction web application version) helped out, especially via PHP’s acceptance of HTML form method=POST data, by …
- a changed second draft agtoslides.php
- a changed second draft agtoslides.ksh
- a changed read_exif_off_image_rotate.php
- a changed client_browsing.htm inhouse client browsing tool (which can also sit alone)
… or via arrangements below.
Previous relevant Animated GIF Slide Extraction Primer Tutorial is shown below.
Would you believe …
- the extraction of an HTML video element still is not too hard using that HTML video element object as the first parameter to a [canvasContext].drawImage method call (as you might recall reading the recent Canvas DrawImage First Parameter Primer Tutorial) … whereas …
- the extraction of an HTML animated GIF image (ie. img) element still is a lot harder, regarding only the clientside Javascript side of web applications because using that animated GIF img object as that first parameter to a [canvasContext].drawImage method call results only in the first still (or slide) of that animated GIF
? And so, to proceed with our “Animated GIF Slide Extraction” web application where a user can ask for the still (or slide) to be honed in on, needed us to design it so that a …
- an HTML and Javascript parent (clientside) extract_ag_slide_huh_of.html Animated GIF Slide Extraction web application (or Animated GIF Slide Extraction via User Interaction web application version) calls …
- serverside PHP agtoslides.php iframe hosted child web application … calling, via shell_exec, a …
- Korn Shell agtoslides.ksh script … facilitating call of …
- ImageMagick convert command based …
 
 convert -coalesce [animatedGIFimageFileName] [outputPNGoutputFilespec]
 
… looking arrangement could fulfil our requirements, so far, where the user can supply …
- [animatedGIFimageFileName] … and …
- slide number to extract (which can be entered as a percentage, being as our “HTML and Javascript parent (clientside) web application” logics are capable of determining an animated GIF’s …
- number of slides (PHP extracts) … and, albeit not needed so far, with this project …
- duration of an animated GIF “run through”
 ) 
… in …
var ij=0;
/** @param {Uint8Array} uint8 */
function isGifAnimated(uint8) { // thanks to https://stackoverflow.com/questions/69564118/how-to-get-duration-of-gif-image-in-javascript#:~:text=Mainly%20use%20parseGIF()%20%2C%20then,duration%20of%20a%20GIF%20image.
  if (origgifloc == '') { origgifloc=gifloc; }
  pbefore='';
  //ij=0;
  let duration = 0;
  for (let i = 0, len = uint8.length; i < len; i++) {
    if (uint8[i] == 0x21
      && uint8[i + 1] == 0xF9
      && uint8[i + 2] == 0x04
      && uint8[i + 7] == 0x00)
    {
      const delay = (uint8[i + 5] << 8) | (uint8[i + 4] & 0xFF);
      duration += delay < 2 ? 10 : delay;
    
 
  if (doit || gifloc.indexOf('%') != -1 || 1 == 1) {
    ij++;
    doit=true;
    gifloc=origgifloc;
    pbefore='' + ('gifloc=' + gifloc + ' and duration=' + eval(duration / 100) + ' and ij=' + ij + ' ');
    if (origgifloc.indexOf('%') != -1) { gifloc='' + Math.round(eval(eval(gifloc.replace('%','')) * eval('' + ij) / 100.0)); }
    //document.title='' + pbefore + ' ... ' + gifloc;
  }
    }
  }
  if (eval(duration / 100) <= 0.11) {
  return 0;
  }
  //if (gifloc.indexOf('%') != -1) {
  //  alert('' + eval(duration / 100) + ' vs ' + delay);
  //  gifloc=gifloc.replace('%','');
  //}
  if (1 == 5 && canextract > 0) {
    alert('' + eval(duration / 100));
  } else {
  var newimg=new Image();
  newimg.onload = function(){
    ih=newimg.height;
    iw=newimg.width;
    document.getElementById('dimg').style.width='' + eval(1 * newimg.width) + 'px';
    document.getElementById('dimg').style.height='' + eval(1 * newimg.height) + 'px';
    document.getElementById('dimg').style.background='linear-gradient(rgba(255,255,255,0.9),rgba(255,255,255,0.9)),url(' + gifurl + ')';
    //document.getElementById('dimg').style.backgroundPosition='' + iw + 'px ' + ih + 'px';
    document.getElementById('dimg').style.backgroundPosition='0px 0px';
    document.getElementById('dimg').style.backgroundSize='' + newimg.width + 'px ' + newimg.height + 'px';
    document.getElementById('dimg').style.backgroundRepeat='no-repeat';
    document.getElementById('dimg').src='#';
    document.getElementById('dimg').src=gifurl;
    document.getElementById('mygimage').style.opacity='0.1';
  };
  
  newimg.src=gifurl;
  goi=document.getElementById('mygimage');
  goisrc=gifurl;
  document.getElementById('mygimage').src=gifurl;
  //newimg.src=gifurl;
  setTimeout(function(){
      jjform = new FormData();
      jjxhr = new XMLHttpRequest();
      document.getElementById('agname').value=gifurl;
      document.getElementById('mygimage').title='Finding slide ' + eval(1 + eval(eval(-1 + eval('' + gifloc.replace('%',''))) % ij)) + ' of ' + ij + ' ... please wait ...';
      document.getElementById('slidenumber').value='' + eval(1 + eval(eval(-1 + eval('' + gifloc.replace('%',''))) % ij));
      jjform.append('agname', gifurl);
      jjform.append('slidenumber', '' + eval(1 + eval(      eval(-1 + eval('' + gifloc.replace('%','')))     % ij)));
      jjxhr.onreadystatechange = oneslidedu;
      //jjxhr.responseType = "Document";
      jjxhr.open('post', './agtoslides.php', true);
      if (1 == 1) {
      if (eval('' + document.getElementById('agname').value.length) < 400) {
      //document.getElementById('dimg').style.opacity='0.1';
      document.body.style.cursor='progress';
      document.getElementById('myif').src='./agtoslides.php?agname=' + encodeURIComponent(document.getElementById('agname').value) + '&slidenumber=' + encodeURIComponent(document.getElementById('slidenumber').value);
      } else {
      //document.getElementById('dimg').style.opacity='0.1';
      document.body.style.cursor='progress';
      document.getElementById('mysub').click();
      }
      } else {
      jjxhr.send(jjform);
      }
  }, 5000);
  }
  return duration / 100; // if 0.1 is not an animated GIF
}
… and to try this out you can turn the iframe below into a user interaction one via a click below …
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
 
                    								


