Media web applications such as that of Video via Image Filter and Canvas Magnifier Mobile Tutorial can be expected to consider cross-browser and cross-platform issues to work to the extent that sometimes you need Javascript “if” code blocks to differentiate the code required to make the web application work for as many platforms and web browsers as possible.
You will often find that Internet Explorer and (Microsoft) Edge web browsers are that little bit different in behaviour to the other browsers. Can think of “details/summary” elements, or lack thereof, as a case in point. Today, trying out the video web application of interest, as it was then, on Internet Explorer we had no success with the smaller canvas sub-windows working. Is Internet Explorer good for debugging such scenarios? Yes, it is very good with its F12 Developer Tools. Starting up these F12 Developer Tools and restarting the web application, we found the problem to be …
SCRIPT1002: Syntax error
processor.js (517,50)
… which is very good and precise information. It took us a while to tweak that “Syntax error” means just that, a syntax error. And you’ll laugh at the fix. Going off though, on the “timing” of events “garden path” we think it’s a good idea, anyway, in …
- the parent HTML/Javascript webpage the changed video_mask_via_canvas.html to …
<script type="text/javascript" src="processor.js" defer></script>
… to defer (for timing comfort purposes) the call of … - the changed external Javascript processor.js … with the (external) Javascript code (didn’t you promise not to laugh?) changed from …
document.addEventListener("DOMContentLoaded", () => {
processor.doLoad();
});
… to …
document.addEventListener("DOMContentLoaded", function() {
processor.doLoad();
});
Sad, huh?! Still, better late than never. Have a look at some of this with today’s PDF presentation. Just before we go, it is good to say, even more important than such a discovery is on the “plus” (Internet Explorer and Edge) side, it is more important as a programmer to test that such a change doesn’t stuff something that was working already (such as other non-mobile browsers, and mobile platforms) elsewhere. Our tests did not show this as a problem, but in our view it is more a cruel blow to a user when something used to work, and changes made “cruel” that situation, later. We feel that way about the importance of backward compatibility, in the same way of thinking.
Previous relevant Video via Image Filter and Canvas Magnifier Mobile Tutorial is shown below.
We hadn’t tested the work of yesterday’s Video via Image Filter and Canvas Magnifier Tutorial on mobile platforms, and because it is so mouse event sensitive, yes, there are quite a few issues.
Also, on an iPad, the issues were not as severe as on an iPhone, that smaller screen size causing unique issues, such as the floating extra window video play we have to think about further.
One we did not expect with iOS Safari was the preference that platform has for [element].addEventListener(‘change’,[functionCode]) rather than [element].onchange=[functionCode] as we read about at this useful link, thanks. With iOS generally, it is often a good idea with logic that involves media operations to involve a button click to set off proceedings. Whether this can be a programmatical click is debatable on occasions, and can remember this programmatical approach not working for the playing of audio without real user button pressing.
For some reason we could not get the “overlay” tactics of yesterday involving “position:absolute;left:[asCalculatedLeftForLHCanvas];top:[asCalculatedTopForLHCanvas];” and “z-index:[bigZ]” to work for iOS Safari, and so settled for an HTML img displayed nearby.
So, we have the changed video_mask_via_canvas.html that has this live run link for you to try on mobile or non-mobile today, and which supervises the changed external Javascript processor.js script.
Previous relevant Video via Image Filter and Canvas Magnifier Tutorial is shown below.
When thinking of the HTML img element’s relationship with the HTML5 canvas element there are loads of importing and exporting possibilities between them, but one that just has to live in the img world alone are …
- CSS filters do not transfer to a canvas when using the [canvasContext].drawImage() method … but one that works is …
- magnifier can work with the onmousemove (or mobile ontouchmove) event of the left canvas and manipulate an image and “project” it into the right hand canvas … a method you often see on fashion eCommerce websites, and which we got great help about with this great link, thanks
But those CSS filters …
<style>
img.sepia {
-webkit-filter: sepia(1);
filter: sepia(1);
}
img.saturate {
-webkit-filter: saturate(8);
filter: saturate(8);
}
img.hue-rotate {
-webkit-filter: hue-rotate(90deg);
filter: hue-rotate(90deg);
}
img.opacity {
-webkit-filter: opacity(.2);
filter: opacity(.2);
}
img.brightness {
-webkit-filter: brightness(3);
filter: brightness(3);
}
img.contrast {
-webkit-filter: contrast(4);
filter: contrast(4);
}
img.blur {
-webkit-filter: blur(5px);
filter: blur(5px);
}
img.drop-shadow {
-webkit-filter: drop-shadow(16px 16px 10px rgba(0,0,0,0.9));
filter: drop-shadow(16px 16px 10px rgba(0,0,0,0.9));
}
</style>
… inspired by this wonderful link, thanks … should not be rejected on that count (as above). We have (two of our usual) CSS “overlay” (suspect) friends that can come to our rescue, those being …
- position:absolute property (the left and top and width and height calculations helped out via the [rightHandCanvasElement].getBoundingClientRect() method)
- z-index
… arranging the HTML img element float above the right hand canvas (or below it) depending on the option chosen in today’s much busier dropdown “mode of use” menu in our “Video/Canvas/Image Manipulations Web Application”.
So, adding onto the progress to yesterday’s Video via Canvas File API Tutorial we have the changed video_mask_via_canvas.html that has this live run link for you to try, and which supervises the changed external Javascript processor.js script.
Previous relevant Video via Canvas File API Tutorial is shown below.
Yes, some of you probably guessed correctly, regarding where we’d go after yesterday’s Video Pixel Manipulation via Canvas Tutorial. As a background to this, we see for web applications, two primary source “partitions”, those being …
- around the “net” (in the server wooooooorrrrrlllllld, in the public areas of the Internet, which are not in “the dark web”, that is) via an absolute URL (to the same domain or beyond) and/or relative URL (in relation to the URL “home” place on the web server of the same domain as where you launched it … which we catered for yesterday, though quietly we’d have allowed absolute URLs too, it’s just that cross-domain restrictions make us shy about publicizing that) … versus …
- on the client computer (or device)
… and, yes, for all those who guessed we’d try to cater for image and/or video data coming from this client source, you are correct, and will probably win a cupie doll at some stage in your life, maybe even into the future, and we’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 “you don’t give me anything” we say “don’t say we don’t give you anything”.
Where best to read about the File API (that came in with HTML5) that helps out so much here? We really like, and think, HTML5 Rocks! While you’re in the mood here, stay on the same domain, and read how we incorporate the “capture” 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’re own media and “File API” it into place rather than looking about the device or computer hard disk, as you can read about at HTML5 Rock’s Capturing Audio & Video in HTML5.
What else have we included today into the mix? That’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.
If these features interest you, take a look at the changed video_mask_via_canvas.html that has this live run link for you to try, and which supervises the unchanged external Javascript processor.js.
Previous relevant Video Pixel Manipulation via Canvas Tutorial is shown below.
The recent Video Mask via Canvas Primer Tutorial got us started on a dynamic video manipulation tool that we see as …
- “see through” or masking functionality … and onto that today, we’d like to add two more pixel manipulation ideas, those being …
- grayscale … and …
- colour inversion
… so that aforesaid mentioned Javascript function becomes …
computeFrame: function() {
var imr=146;
var img=117;
var imb=101;
var mode=0; // see through
var bright=0;
if (document.getElementById('mr')) {
if (document.getElementById('mr').value != '') {
imr=eval('' + document.getElementById('mr').value);
}
}
if (document.getElementById('mg')) {
if (document.getElementById('mg').value != '') {
img=eval('' + document.getElementById('mg').value);
}
}
if (document.getElementById('mb')) {
if (document.getElementById('mb').value != '') {
imb=eval('' + document.getElementById('mb').value);
}
}
this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
let l = frame.data.length / 4;
if (document.getElementById('mode')) {
mode=eval('' + document.getElementById('mode').value);
if (mode == 1) { // going grey
for (let i = 0; i < l; i++) {
bright = 0.34 * frame.data[i * 4 + 0] + 0.5 * frame.data[i * 4 + 1] + 0.16 * frame.data[i * 4 + 2];
frame.data[i * 4 + 0]=bright;
frame.data[i * 4 + 1]=bright;
frame.data[i * 4 + 2]=bright;
}
} else if (mode == 2) { // invert colours
for (let i = 0; i < l; i++) {
frame.data[i * 4 + 0]=255 - frame.data[i * 4 + 0];
frame.data[i * 4 + 1]=255 - frame.data[i * 4 + 1];
frame.data[i * 4 + 2]=255 - frame.data[i * 4 + 2];
}
}
}
if (mode == 0) {
for (let i = 0; i < l; i++) {
let r = frame.data[i * 4 + 0];
let g = frame.data[i * 4 + 1];
let b = frame.data[i * 4 + 2];
if ((Math.abs(r - imr) <= 43 && Math.abs(g - img) <= 43 && Math.abs(b - imb) <= 43) || (1 == 6 && r > 200)) { frame.data[i * 4 + 3] = 0; }
}
}
this.ctx2.putImageData(frame, 0, 0);
return;
}
};
As well, we see the video itself as a parameterizable concept of the web application (as part of our continuing “genericization drive”) and offer logics to handle a user entered relative URL as far as that goes. Perhaps here, though, you can imagine where we’ll go with this on the next occasion.
The changed video_mask_via_canvas.html has this live run link for you to try, and which supervises the changed external Javascript processor.js).
Previous relevant Video Mask via Canvas Primer Tutorial is shown below.
Thanks to Manipulating Video using Canvas we have a …
- video … meets …
- canvas … may meet …
- image … or background colour … masking mechanism
… today with a new web application (called video_mask_via_canvas.html) live run (supervising external Javascript processor.js) 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 as per …
computeFrame: function() {
this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
let l = frame.data.length / 4;
for (let i = 0; i < l; i++) {
let r = frame.data[i * 4 + 0];
let g = frame.data[i * 4 + 1];
let b = frame.data[i * 4 + 2];
if ((Math.abs(r - 146) <= 43 && Math.abs(g - 117) <= 43 && Math.abs(b - 101) <= 43) || (1 == 6 && r > 200)) { frame.data[i * 4 + 3] = 0; }
}
this.ctx2.putImageData(frame, 0, 0);
return;
}
};
… where we “masked” near to the rgb(146,117,101) dark brown (the rgb() details of which we gleaned via our MacBook Pro’s Digital Color Meter desktop application you can read more about at Digital Colour Meter on Mac Laptop Tutorial) that is near to our dog Luna’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 “dark brown” 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.
We hope this is of interest to you.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.