{"id":45152,"date":"2019-06-04T03:01:12","date_gmt":"2019-06-03T17:01:12","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=45152"},"modified":"2019-06-03T20:18:26","modified_gmt":"2019-06-03T10:18:26","slug":"video-pixel-manipulation-via-canvas-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/video-pixel-manipulation-via-canvas-tutorial\/","title":{"rendered":"Video Pixel Manipulation via Canvas 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 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","protected":false},"excerpt":{"rendered":"<p>The recent Video Mask via Canvas Primer Tutorial got us started on a dynamic video manipulation tool that we see as &#8230; &#8220;see through&#8221; or masking functionality &#8230; and onto that today, we&#8217;d like to add two more pixel manipulation &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/video-pixel-manipulation-via-canvas-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,184,224,330,409,2440,576,578,590,2685,652,1918,997,1302,1319,1369],"class_list":["post-45152","post","type-post","status-publish","format-standard","hentry","category-elearning","category-event-driven-programming","category-tutorials","tag-background-colour","tag-background-image","tag-canvas","tag-colour","tag-digital-colour-meter","tag-external-javascript","tag-grayscale","tag-html","tag-html5","tag-image","tag-invert","tag-javascript","tag-pixel","tag-programming","tag-transparency","tag-tutorial","tag-video"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/45152"}],"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=45152"}],"version-history":[{"count":4,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/45152\/revisions"}],"predecessor-version":[{"id":45156,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/45152\/revisions\/45156"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=45152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=45152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=45152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}