{"id":63602,"date":"2024-05-14T03:01:24","date_gmt":"2024-05-13T17:01:24","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=63602"},"modified":"2024-05-14T14:57:36","modified_gmt":"2024-05-14T04:57:36","slug":"image-element-dynamic-css-canvas-context-filter-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/image-element-dynamic-css-canvas-context-filter-tutorial\/","title":{"rendered":"Image Element Dynamic CSS Canvas Context Filter Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html\"><img decoding=\"async\" style=\"float:left;border: 15px solid pink;\" alt=\"Image Element Dynamic CSS Canvas Context Filter Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera_yetmore.jpg\" title=\"Image Element Dynamic CSS Canvas Context Filter Tutorial\"   \/><\/a><p class=\"wp-caption-text\">Image Element Dynamic CSS Canvas Context Filter Tutorial<\/p><\/div>\n<p>Ask and ye shall discover, &#8216;guv<sup>n<\/sup><sub>er<\/sub>.  Ask &#8230;<\/p>\n<p><code><br \/>\n<a target=_blank title='image to canvas include css filters' href='https:\/\/www.google.com\/search?q=image+to+canvas+include+css+filters&#038;sca_esv=9eb05f6e21efd95c&#038;sca_upv=1&#038;rlz=1C5CHFA_enAU973AU973&#038;sxsrf=ADLYWILD9syagOYVVn2DI54tOQ5KaTbKTA%3A1715563713159&#038;ei=wWxBZpS4CYnlseMP0q-rOA&#038;ved=0ahUKEwjUnNntvImGAxWJcmwGHdLXCgcQ4dUDCBA&#038;uact=5&#038;oq=image+to+canvas+include+css+filters&#038;gs_lp=Egxnd3Mtd2l6LXNlcnAiI2ltYWdlIHRvIGNhbnZhcyBpbmNsaWRlIGNzcyBmaWx0ZXJzMgcQIRigARgKSIShAVDGIliDnwFwA3gBkAEAmAGaAqABwTGqAQYwLjI5Lja4AQPIAQD4AQGYAiagAqszqAIRwgIKEAAYsAMY1gQYR8ICBBAjGCfCAgoQIxiABBgnGIoFwgIREAAYgAQYkQIYsQMYgwEYigXCAhcQLhiABBiRAhixAxjRAxiDARjHARiKBcICChAAGIAEGEMYigXCAhEQLhiABBixAxjRAxiDARjHAcICCxAuGIAEGLEDGIMBwgILEAAYgAQYsQMYgwHCAgcQIxgnGOoCwgIUEAAYgAQY4wQYtAIY6QQY6gLYAQHCAgsQABiABBiRAhiKBcICEBAAGIAEGLEDGEMYgwEYigXCAg4QABiABBiRAhixAxiKBcICDRAAGIAEGEMYyQMYigXCAg0QABiABBixAxhDGIoFwgIFEAAYgATCAgoQABiABBgUGIcCwgILEAAYgAQYhgMYigXCAgYQABgWGB7CAggQABgWGB4YD8ICBRAhGKABwgIFECEYnwXCAgYQIRgVGAqYAwyIBgGQBgi6BgYIARABGAGSBwYzLjI5LjagB6PDAQ&#038;sclient=gws-wiz-serp'>image to canvas include css filters<\/a><br \/>\n<\/code><\/p>\n<p> &#8230; which got us to the excellent &#8230;<\/p>\n<p><code><br \/>\n<a target=_blank href='https:\/\/stackoverflow.com\/questions\/30408939\/how-to-save-image-from-canvas-with-css-filters' title='How to save image from canvas with CSS filters'>How to save image from canvas with CSS filters<\/a><br \/>\n<\/code><\/p>\n<p> &#8230; including the great <a target=_blank title='HTML Canvas element information from w3schools' href='http:\/\/www.w3schools.com\/tags\/ref_canvas.asp'>canvas<\/a> advice &#8230;<\/p>\n<blockquote cite='https:\/\/stackoverflow.com\/questions\/30408939\/how-to-save-image-from-canvas-with-css-filters'>\n<p>There is a little known <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/CanvasRenderingContext2D\/filter\" rel=\"noreferrer\">property<\/a> on the context object, conveniently named <code>filter<\/code>.<\/p>\n<p>This can take a CSS filter as argument and apply it to the bitmap. <del>However, this is <em>not<\/em> part of the official standard and it only works in Firefox so there is the limitation.<\/del>. This has since this answer was originally written become a part of the <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/scripting.html#filters\" rel=\"noreferrer\">official standard<\/a>.<\/p>\n<p>You can check for the existence of this property and use CSS filters if it does, or use a fallback to manually apply the filters to the image if not. The only advantage is really performance when available.<\/p>\n<p>CSS and DOM is a separate world from the bitmaps that are used for images and canvas. The bitmaps themselves are not affected by CSS, only the elements which acts as a looking-glass to the bitmap. The only way is to work with at pixel levels (when <em>context<\/em>&#8216;s filter property is not available).<\/p>\n<p>How to calculate the various filters can be found in the <a href=\"http:\/\/www.w3.org\/TR\/filter-effects\/#ShorthandEquivalents\" rel=\"noreferrer\">Filter Effects Module Level 1<\/a>. Also see <a href=\"http:\/\/www.w3.org\/TR\/SVG\/filters.html\" rel=\"noreferrer\">SVG Filters<\/a> and <a href=\"http:\/\/www.w3.org\/TR\/filter-effects\/#feColorMatrixElement\" rel=\"noreferrer\">Color Matrix<\/a>.<\/p>\n<\/blockquote>\n<p>. Who&#8217;d have known?!  And &#8230; why didn&#8217;t people wake me up at 2:23am <font size=1>(me at my &#8220;clarifying&#8221; best)<\/font> to tell me?  But we digress.<\/p>\n<p>Even so, though this <font color=blue>new canvas involvement<\/font> thinking &#8230;<\/p>\n<p><code><br \/>\n   document.getElementById('animg').onload=function(event){<br \/>\n     <font color=blue>var filt=document.getElementById('selopt').innerText;<br \/>\n     if (document.getElementById('animg').outerHTML.indexOf(' style=\"') != -1) {<br \/>\n     if (document.getElementById('animg').outerHTML.split(' style=\"')[1].split('\"')[0].indexOf('filter:') != -1) {<br \/>\n     filt=document.getElementById('animg').outerHTML.split(' style=\"')[1].split('\"')[0].split('filter:')[1].split(';')[0].trim();<br \/>\n     document.getElementById('dcanvas').innerHTML='&lt;details id=dtlcanvas&gt;&lt;summary id=sumcanvas&gt;Canvas view below ...&lt;\/summary&gt;&lt;br&gt;&lt;br&gt;&lt;canvas id=mycanvas width=' + lastim.width + ' height=' + lastim.height + '&gt;&lt;\/canvas&gt;&lt;\/details&gt;';<br \/>\n     } else {<br \/>\n     document.getElementById('dcanvas').innerHTML='&lt;details id=dtlcanvas&gt;&lt;summary id=sumcanvas&gt;Canvas view below ...&lt;\/summary&gt;&lt;br&gt;&lt;br&gt;&lt;canvas style=\"' + document.getElementById('animg').outerHTML.split(' style=\"')[1].split('\"')[0] + '\" id=mycanvas width=' + lastim.width + ' height=' + lastim.height + '&gt;&lt;\/canvas&gt;&lt;\/details&gt;';<br \/>\n     }<br \/>\n     } else {<\/font><br \/>\n     document.getElementById('dcanvas').innerHTML='&lt;details id=dtlcanvas&gt;&lt;summary id=sumcanvas&gt;Canvas view below ...&lt;\/summary&gt;&lt;br&gt;&lt;br&gt;&lt;canvas id=mycanvas width=' + lastim.width + ' height=' + lastim.height + '&gt;&lt;\/canvas&gt;&lt;\/details&gt;';<br \/>\n     <font color=blue>}<\/font><br \/>\n     lastca=document.getElementById('mycanvas');<br \/>\n     lastcac=lastca.getContext('2d');<br \/>\n     <font color=blue>if (filt != '') {   lastcac.filter=filt; }<\/font><br \/>\n     lastcac.drawImage(event.target, 0, 0);<br \/>\n     lastim=document.getElementById('animg');<br \/>\n   };<br \/>\n   document.getElementById('animg').src=document.getElementById('animg').src;<br \/>\n<\/code><\/p>\n<p> &#8230; offers new context menu functionality, and so we are keen to include it, it has not changed our sharing hashtag powered logic.<\/p>\n<p>If at this stage you are forgetting the original issue &#8230; let me explain it from a new outlook &#8230;<\/p>\n<ul>\n<li>you&#8217;ve got an image or have taken one with your device&#8217;s Camera app &#8230;<\/li>\n<li>you want to apply some CSS filter &#8220;effects&#8221; <font size=1>&#8230; yeh, yeh, yeh &#8230; we realize all the big players have this covered &#8230; but, remember, you want to <i>program<\/i><\/font> &#8230;<\/li>\n<li>you want to share it &#8230; for example, on Google Chrome you have a context menu option &#8220;Create QR code for this image&#8221; &#8230; just supposing you choose that option &#8230;<\/li>\n<li>QR code appears on the screen &#8230; and with your device&#8217;s &#8230;<\/li>\n<li>Camera app you access the URL off that QR code <font size=1>(in the way Covid taught so many of us to do)<\/font> &#8230; huh?!!! &#8230;<br \/>\n<img decoding=\"async\" src=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/crux_of_issue.jpg\"><\/img> &#8230;<\/li>\n<li>yes, sadly, the image filter affects you applied do not flow through &#8230;<\/li>\n<\/ul>\n<p> &#8230; well, it is this issue we&#8217;re talking about with this thread of blog postings.<\/p>\n<p>Okay, so, <a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html--GETME\">today&#8217;s changed<\/a> <a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html--GETME\">third draft<\/a>  <a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html\">Image Element Dynamic CSS<\/a> web application you can also <a href='#myioc'>try below<\/a>, gets us further along our path, and, indeed, it may be at its end.  Even so that sharing happens with the img element processing and the canvas involvement is supplementary only (in the sense that the canvas context menu has no Share type of option, though it has Copy and Save As and an Inspect option which is not useful), moving on from yesterday&#8217;s <a title='Image Element Dynamic CSS Hashtag Sharing Tutorial' href='#iedcsshst'>Image Element Dynamic CSS Hashtag Sharing Tutorial<\/a>.<\/p>\n<p>We&#8217;ll see if we can discover anything else?<\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/image-element-dynamic-css-canvas-context-filter-tutorial\/'>Image Element Dynamic CSS Canvas Context Filter Tutorial<\/a>.<\/p-->\n<hr>\n<p id='iedcsshst'>Previous relevant <a target=_blank title='Image Element Dynamic CSS Hashtag Sharing Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/image-element-dynamic-css-hashtag-sharing-tutorial\/'>Image Element Dynamic CSS Hashtag Sharing Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html\"><img decoding=\"async\" style=\"float:left;border: 15px solid pink;\" alt=\"Image Element Dynamic CSS Hashtag Sharing Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera_more.jpg\" title=\"Image Element Dynamic CSS Hashtag Sharing Tutorial\"   \/><\/a><p class=\"wp-caption-text\">Image Element Dynamic CSS Hashtag Sharing Tutorial<\/p><\/div>\n<p>Our recent realization that &#8220;hashtag sharing&#8221; could be the alternative to our &#8220;PHP mail&#8221; exploits of the past meant that &#8230;<\/p>\n<ul>\n<li>that &#8220;proof of concept&#8221; idea we had of involving the HTML canvas sharing conduit we wanted to tell about, as yet, has not happened because our CSS filters did not flow through via the [canvasContext].drawImage functionality &#8230; was not the end of our sharing endeavours because &#8230;<\/li>\n<li>hashtag sharing of the image outerHTML alternative approach &#8230;<\/li>\n<\/ul>\n<p> &#8230; comes into play, today.  We&#8217;ll see what can be done at the canvas element end regarding more &#8220;filter CSS flow through&#8221; research into the future. Meanwhile, also below see a mechanism by which users can tweak dropdown CSS styling options &#8230;<\/p>\n<p><code><br \/>\n function doemail() {<br \/>\n    var emailee=prompt('Please enter email address to share with.', '');<br \/>\n    if (emailee == null) { emailee=''; }<br \/>\n    if (emailee.indexOf('@') != -1) {<br \/>\n       document.getElementById('aemail').href='mailto:' + emailee + '?subject=Image%20Filters&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#image=' + encodeURIComponent(document.getElementById('animg').outerHTML));<br \/>\n       document.getElementById('aemail').click();<br \/>\n    }<br \/>\n }<br \/>\n<br \/>\n function dosms() {<br \/>\n    var emailee=prompt('Please enter SMS number to share with.', '');<br \/>\n    if (emailee == null) { emailee=''; }<br \/>\n    if (emailee != '' && emailee.trim().replace(\/0\/g,'').replace(\/1\/g,'').replace(\/2\/g,'').replace(\/3\/g,'').replace(\/4\/g,'').replace(\/5\/g,'').replace(\/6\/g,'').replace(\/7\/g,'').replace(\/8\/g,'').replace(\/9\/g,'') == '') {<br \/>\n       document.getElementById('asms').href='sms:' + emailee + '&body=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0] + '#image=' + encodeURIComponent(document.getElementById('animg').outerHTML));<br \/>\n       document.getElementById('asms').click();<br \/>\n    }<br \/>\n }<br \/>\n <br \/>\n function embellish() {<br \/>\n   var newstyling=prompt('Optionally change styling.', document.getElementById('selopt').innerText);<br \/>\n   if (newstyling == null) { newstyling=''; }<br \/>\n   if (newstyling != document.getElementById('selopt').innerText && newstyling.indexOf(':') != -1) {<br \/>\n      document.getElementById('selopt').innerText=newstyling;<br \/>\n      ais=document.getElementById('animg').src;<br \/>\n      document.getElementById('danimg').innerHTML=\"&lt;img style=\\\"\" + newstyling + \"\\\" id=animg src=\\\"\" + ais + \"\\\"&gt;&lt;\/img&gt;\";<br \/>\n   }<br \/>\n }<br \/>\n<\/code><\/p>\n<p>And so, onto yesterday&#8217;s <a title='Image Element Dynamic CSS Primer Tutorial' href='#iedcsspt'>Image Element Dynamic CSS Primer Tutorial<\/a> we have <a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html-GETME\">a changed<\/a> <a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html-GETME\">second draft<\/a> <a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html\">Image Element Dynamic CSS<\/a> web application you can also <a href='#myioc'>try below<\/a>.<\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/image-element-dynamic-css-hashtag-sharing-tutorial\/'>Image Element Dynamic CSS Hashtag Sharing Tutorial<\/a>.<\/p-->\n<hr>\n<p id='iedcsspt'>Previous relevant <a target=_blank title='Image Element Dynamic CSS Primer Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/image-element-dynamic-css-primer-tutorial\/'>Image Element Dynamic CSS Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html\"><img decoding=\"async\" style=\"float:left;border: 15px solid pink;\" alt=\"Image Element Dynamic CSS Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.gif\" title=\"Image Element Dynamic CSS Primer Tutorial\"   \/><\/a><p class=\"wp-caption-text\">Image Element Dynamic CSS Primer Tutorial<\/p><\/div>\n<p>We&#8217;re curious about something and need to start a new &#8220;proof of concept&#8221; (first draft) phase involving, at this early stage &#8230;<\/p>\n<ul>\n<li>HTML <a target=_blank title='HTML img tag information from w3schools' href='http:\/\/www.w3schools.com\/tags\/tag_img.asp'>img<\/a> elements &#8230;<\/li>\n<li>applied dynamic user selected CSS (with an emphasis on dropdown suggested <a target=_blank title='CSS filters' href='https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/filter'>filter<\/a> property usage) &#8230; powered by &#8230;<\/li>\n<li>browsed for or image URL defined content logic<\/li>\n<\/ul>\n<p>Luckily we have precedents for all this, and this can be a good start!  So please try our <a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html_GETME\">first draft<\/a> <a target=_blank href=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html\">Image Element Dynamic CSS<\/a> web application you can also try below.<\/p>\n<p><iframe id=myioc src=\"https:\/\/www.rjmprogramming.com.au\/HTMLCSS\/image_filters_off_camera.html\" style=\"width:100%;height:2100px;\"><\/iframe><\/p>\n<p>Tomorrow&#8217;s work will see whether our theory comes to fruition!<\/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='#d63588' onclick='var dv=document.getElementById(\"d63588\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/property\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d63588' 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='#d63596' onclick='var dv=document.getElementById(\"d63596\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/share\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d63596' 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='#d63602' onclick='var dv=document.getElementById(\"d63602\"); 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='d63602' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Ask and ye shall discover, &#8216;guvner. Ask &#8230; image to canvas include css filters &#8230; which got us to the excellent &#8230; How to save image from canvas with CSS filters &#8230; including the great canvas advice &#8230; There is &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/image-element-dynamic-css-canvas-context-filter-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":[184,1604,2105,3865,281,354,367,1683,380,431,2229,557,576,590,599,652,997,3449,2232,1069,1133,1137,1159,1209,1212,1319,1418],"class_list":["post-63602","post","type-post","status-publish","format-standard","hentry","category-elearning","category-event-driven-programming","category-tutorials","tag-canvas","tag-collaboration","tag-context","tag-context-menu","tag-css","tag-dom","tag-dropdown","tag-dynamic","tag-email","tag-filter","tag-hash","tag-hashtag","tag-html","tag-image","tag-img","tag-javascript","tag-programming","tag-properties","tag-property","tag-right-click","tag-share","tag-sharing","tag-sms","tag-style","tag-styling","tag-tutorial","tag-webpage"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/63602"}],"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=63602"}],"version-history":[{"count":12,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/63602\/revisions"}],"predecessor-version":[{"id":63615,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/63602\/revisions\/63615"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=63602"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=63602"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=63602"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}