{"id":45157,"date":"2019-06-05T03:01:07","date_gmt":"2019-06-04T17:01:07","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=45157"},"modified":"2019-06-05T07:08:05","modified_gmt":"2019-06-04T21:08:05","slug":"video-via-canvas-file-api-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/video-via-canvas-file-api-tutorial\/","title":{"rendered":"Video via Canvas File API Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Video via Canvas File API Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/videomask_via_canvas.jpg\" title=Video via Canvas File API Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Video via Canvas File API Tutorial<\/p><\/div>\n<p>Yes, some of you probably guessed correctly, regarding where we&#8217;d go after yesterday&#8217;s <a title='Video Pixel Manipulation via Canvas Tutorial' href='#vpmct'>Video Pixel Manipulation via Canvas Tutorial<\/a>.  As a background to this, we see for web applications, two primary source &#8220;partitions&#8221;, those being &#8230;<\/p>\n<ul>\n<li>around the &#8220;net&#8221; (in the <i>server<\/i> wooooooorrrrrlllllld, in the public areas of the Internet, which are not in &#8220;the dark web&#8221;, that is) via an absolute URL (to the same domain or beyond) and\/or relative URL (in relation to the URL &#8220;home&#8221; place on the web server of the same domain as where you launched it &#8230; which we catered for yesterday, though quietly we&#8217;d have allowed absolute URLs too, it&#8217;s just that cross-domain restrictions make us shy about publicizing that) &#8230; versus &#8230;<\/li>\n<li>on the <i>client<\/i> computer (or device)<\/li>\n<\/ul>\n<p> &#8230; and, yes, for all those who guessed we&#8217;d try to cater for image and\/or video data coming from this <i>client<\/i> source, you are correct, and will probably win a cupie doll at some stage in your life, maybe even into the future, and we&#8217;d like to take some responsibility for the positive thoughts we sent your way in your future endeavours in this regard, and would like to have it be noted that when you said &#8220;you don&#8217;t give me anything&#8221; we say &#8220;don&#8217;t say we don&#8217;t give you anything&#8221;.<\/p>\n<p>Where best to read about the <a target=_blank title='Great link' href='http:\/\/www.html5rocks.com\/en\/tutorials\/file\/dndfiles\/'>File API<\/a> (that came in with HTML5) that helps out so much here?  We really like, and think, <a target=_blank title='Great link' href='http:\/\/www.html5rocks.com\/en\/tutorials\/file\/dndfiles\/'>HTML5 Rocks<\/a>!  While you&#8217;re in the mood here, stay on the same domain, and read how we incorporate the &#8220;capture&#8221; attribute with the input type=file video and image browse buttons, so that for a lot of mobile devices and platforms you can capture you&#8217;re own media and &#8220;File API&#8221; it into place rather than looking about the device or computer hard disk, as you can read about at HTML5 Rock&#8217;s <a target=_blank title='Capturing Audio &#038; Video in HTML5' href='https:\/\/www.html5rocks.com\/en\/tutorials\/getusermedia\/intro\/'>Capturing Audio &#038; Video in HTML5<\/a>.<\/p>\n<p>What else have we included today into the mix?  That&#8217;s right, we nest the video element into an HTML div in order to be able to perhaps scroll around.   We give mechanisms to offset the video and background image masker.  We give a resizing mechanism to the video.<\/p>\n<p>If these features interest you, take a look at <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html--GETME\" title=\"video_mask_via_canvas.html\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html--GETME\" title=\"video_mask_via_canvas.html\">video_mask_via_canvas.html<\/a> that has this <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html\" title=\"Click picture\">live run<\/a> link for you to try, and which supervises the unchanged external Javascript <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/processor.js-GETME\" title=\"processor.js\">processor.js<\/a>.<\/p>\n<hr>\n<p id='vpmct'>Previous relevant <a target=_blank title='Video Pixel Manipulation via Canvas Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/video-pixel-manipulation-via-canvas-tutorial\/'>Video Pixel Manipulation via Canvas Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Video Pixel Manipulation via Canvas Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/videomaskviacanvas.jpg\" title=Video Pixel Manipulation via Canvas Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Video Pixel Manipulation via Canvas Tutorial<\/p><\/div>\n<p>The recent <a title='Video Mask via Canvas Primer Tutorial' href='#vmcpt'>Video Mask via Canvas Primer Tutorial<\/a> got us started on a dynamic video manipulation tool that we see as &#8230;<\/p>\n<ul>\n<li>&#8220;see through&#8221; or masking functionality &#8230; and onto that today, we&#8217;d like to add two more pixel manipulation ideas, those being &#8230;<\/li>\n<li>grayscale &#8230; and &#8230;<\/li>\n<li>colour inversion<\/li>\n<\/ul>\n<p> &#8230; so that aforesaid mentioned Javascript function <b>becomes<\/b> &#8230;<\/p>\n<p><code><br \/>\n    computeFrame: function() {<br \/>\n      var imr=146;<br \/>\n      var img=117;<br \/>\n      var imb=101;<br \/>\n      <b>var mode=0; \/\/ see through<br \/>\n      var bright=0;<\/b><br \/>\n      if (document.getElementById('mr')) {<br \/>\n      if (document.getElementById('mr').value != '') {<br \/>\n      imr=eval('' + document.getElementById('mr').value);<br \/>\n      }<br \/>\n      }<br \/>\n      if (document.getElementById('mg')) {<br \/>\n      if (document.getElementById('mg').value != '') {<br \/>\n      img=eval('' + document.getElementById('mg').value);<br \/>\n      }<br \/>\n      }<br \/>\n      if (document.getElementById('mb')) {<br \/>\n      if (document.getElementById('mb').value != '') {<br \/>\n      imb=eval('' + document.getElementById('mb').value);<br \/>\n      }<br \/>\n      }<br \/>\n      this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);<br \/>\n      let frame = this.ctx1.getImageData(0, 0, this.width, this.height);<br \/>\n          let l = frame.data.length \/ 4;<br \/>\n<br \/> <br \/>\n      <b>if (document.getElementById('mode')) {<br \/>\n          mode=eval('' + document.getElementById('mode').value);<br \/>\n          if (mode == 1) {  \/\/ going grey<br \/>\n      for (let i = 0; i &lt; l; i++) {<br \/>\n        bright = 0.34 * frame.data[i * 4 + 0] + 0.5 * frame.data[i * 4 + 1] + 0.16 * frame.data[i * 4 + 2];<br \/>\n        frame.data[i * 4 + 0]=bright;<br \/>\n        frame.data[i * 4 + 1]=bright;<br \/>\n        frame.data[i * 4 + 2]=bright;<br \/>\n      }<br \/>\n          } else if (mode == 2) { \/\/ invert colours<br \/>\n      for (let i = 0; i &lt; l; i++) {<br \/>\n        frame.data[i * 4 + 0]=255 - frame.data[i * 4 + 0];<br \/>\n        frame.data[i * 4 + 1]=255 - frame.data[i * 4 + 1];<br \/>\n        frame.data[i * 4 + 2]=255 - frame.data[i * 4 + 2];<br \/>\n      }<br \/>\n          }<br \/>\n      }   <\/b><br \/>\n<br \/> <br \/>\n      <b>if (mode == 0) {<\/b><br \/>\n      for (let i = 0; i &lt; l; i++) {<br \/>\n        let r = frame.data[i * 4 + 0];<br \/>\n        let g = frame.data[i * 4 + 1];<br \/>\n        let b = frame.data[i * 4 + 2];<br \/>\n        if ((Math.abs(r - imr) &lt;= 43 && Math.abs(g - img) &lt;= 43 && Math.abs(b - imb) &lt;= 43) || (1 == 6 && r &gt; 200)) { frame.data[i * 4 + 3] = 0; }<br \/>\n      }<br \/>\n      <b>}<\/b><br \/>\n      this.ctx2.putImageData(frame, 0, 0);<br \/>\n      return;<br \/>\n    }<br \/>\n  };<br \/>\n<\/code> <\/p>\n<p>As well, we see the video itself as a parameterizable concept of the web application (as part of our continuing &#8220;genericization drive&#8221;) and offer logics to handle a user entered relative URL as far as that goes.  Perhaps here, though, you can imagine where we&#8217;ll go with this on the next occasion.<\/p>\n<p> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html-GETME\" title=\"video_mask_via_canvas.html\">The changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html-GETME\" title=\"video_mask_via_canvas.html\">video_mask_via_canvas.html<\/a> has this <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html\" title=\"Click picture\">live run<\/a> link for you to try, and which supervises <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/processor.js-GETME\" title=\"processor.js\">the changed external Javascript<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/processor.js-GETME\" title=\"processor.js\">processor.js<\/a>).<\/p>\n<hr>\n<p id='vmcpt'>Previous relevant <a target=_blank title='Video Mask via Canvas Primer Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/video-mask-via-canvas-primer-tutorial\/'>Video Mask via Canvas Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Video Mask via Canvas Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.jpg\" title=Video Mask via Canvas Primer Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Video Mask via Canvas Primer Tutorial<\/p><\/div>\n<p>Thanks to <a target=_blank title='Manipulating Video using Canvas' href='https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Canvas_API\/Manipulating_video_using_canvas'>Manipulating Video using Canvas<\/a> we have a &#8230;<\/p>\n<ul>\n<li>video &#8230; meets &#8230;<\/li>\n<li>canvas &#8230; may meet &#8230;<\/li>\n<li>image &#8230; or background colour &#8230; masking mechanism<\/li>\n<\/ul>\n<p> &#8230; today with a new web application (called <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html_GETME\" title=\"video_mask_via_canvas.html\">video_mask_via_canvas.html<\/a>) <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/video_mask_via_canvas.html\" title=\"Click picture\">live run<\/a> (supervising external Javascript <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/processor.js_GETME\" title=\"processor.js\">processor.js<\/a>) whereby a video is accompanied by a left canvas recreation of any one frame of the video as it plays and a right one subject to masking functionality <b style='background-color:rgb(146,117,101);'>as per<\/b> &#8230;<\/p>\n<p><code><br \/>\n    computeFrame: function() {<br \/>\n      this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);<br \/>\n      let frame = this.ctx1.getImageData(0, 0, this.width, this.height);<br \/>\n          let l = frame.data.length \/ 4;<br \/>\n<br \/> <br \/>\n      for (let i = 0; i < l; i++) {\n        let r = frame.data[i * 4 + 0];\n        let g = frame.data[i * 4 + 1];\n        let b = frame.data[i * 4 + 2];\n        <b style='background-color:rgb(146,117,101);'>if ((Math.abs(r - 146) <= 43 &#038;&#038; Math.abs(g - 117) <= 43 &#038;&#038; Math.abs(b - 101) <= 43) || (1 == 6 &#038;&#038; r > 200)) { frame.data[i * 4 + 3] = 0; }<\/b><br \/>\n      }<br \/>\n      this.ctx2.putImageData(frame, 0, 0);<br \/>\n      return;<br \/>\n    }<br \/>\n  };<br \/>\n<\/code> <\/p>\n<p> &#8230; where we &#8220;masked&#8221; near to the rgb(146,117,101) dark brown (the rgb() details of which we gleaned via our MacBook Pro&#8217;s Digital Color Meter desktop application you can read more about at <a target=_blank title='click picture' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/digital-colour-meter-on-mac-laptop-tutorial'>Digital Colour Meter on Mac Laptop Tutorial<\/a>) that is near to our dog Luna&#8217;s liver coloured fur, as the star of the video.   The effect of the masking is a splash of colour around Luna as pixels of that type above near to that liver &#8220;dark brown&#8221; become transparent and let through what is in the background, whether that be that background colour selected by our HTML input type=color colour picker or our HTML input type=text element optionally asking for a relative image URL to use as the masking helper.<\/p>\n<p>We hope this is of interest to you.<\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d45133' onclick='var dv=document.getElementById(\"d45133\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/canvas\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d45133' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d45152' onclick='var dv=document.getElementById(\"d45152\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/pixel\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d45152' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d45157' onclick='var dv=document.getElementById(\"d45157\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/div\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d45157' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Yes, some of you probably guessed correctly, regarding where we&#8217;d go after yesterday&#8217;s Video Pixel Manipulation via Canvas Tutorial. As a background to this, we see for web applications, two primary source &#8220;partitions&#8221;, those being &#8230; around the &#8220;net&#8221; (in &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/video-via-canvas-file-api-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,14,37],"tags":[2682,127,1993,184,2150,224,330,342,409,419,2440,576,578,590,2685,652,760,2521,1918,997,1059,1917,1302,1319,1369],"class_list":["post-45157","post","type-post","status-publish","format-standard","hentry","category-elearning","category-event-driven-programming","category-tutorials","tag-background-colour","tag-background-image","tag-browse","tag-canvas","tag-capture","tag-colour","tag-digital-colour-meter","tag-div","tag-external-javascript","tag-file-api","tag-grayscale","tag-html","tag-html5","tag-image","tag-invert","tag-javascript","tag-media","tag-nest","tag-pixel","tag-programming","tag-resize","tag-scroll","tag-transparency","tag-tutorial","tag-video"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/45157"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=45157"}],"version-history":[{"count":4,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/45157\/revisions"}],"predecessor-version":[{"id":45161,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/45157\/revisions\/45161"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=45157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=45157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=45157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}