A precursor to today’s continuation of “Image Capture Email” web application HTML5 canvas functionality was the previous Image Capture Ajax FormData Upload Canvas Tutorial as that proof of concept that the canvas …
- onclick event could be trapped and coded for (especially regarding non-scribble “discrete click/touch” event logic) … but you’ll know yourself if you’ve coded for some canvas annotation work you need to cater, also for the events …
- touchmove … especially regarding mobile device “scribbling” annotation
- mousemove … especially regarding non-mobile device “scribbling” annotation
- touchend
- mouseup
- touchstart
- mousedown
- mouseover
… that we would have last talked about with Signature Signature Emoji Placeholder Lookup Tutorial‘s world.js external Javascript.
And so, onto the recent Media Capture Asynchronous Ajax FormData Upload Progress Tutorial you can now see an additional “Canvas Annotation” form to offer …
- text (optionally rotated and colour controlled (like others below)) via 1 discrete click (done first)
- line via 2 discrete clicks/touches (done first)
- rectangle via 2 discrete clicks/touches (done first)
- circle via 2 discrete clicks/touches (done first)
- scribble (after 2 second delay)
- end of scribble
- image via 1 discrete click (done first)
… which now features this changed HTML imagecapture.htm‘s live run (just images) (or, for example, live run (all three categories of “media”) for your scrutiny and perusal. The new “Canvas Annotation” sits within the newly worded “More Email and Canvas Annotation Ideas” (first) details/summary (“revealer”) HTML element (except for Internet Explorer nor Microsoft Edge web browsers, that is). So far, we leave you with native web browser functionality “smarts” regarding canvas elements, the “not to be sneezed at” (Google Chrome example options) …
- Copy image
- Save Image As
… that could be your means to construct your own email attachment via a paste operation into an (client) email (application) message body.
Previous relevant Media Capture Asynchronous Ajax FormData Upload Progress Tutorial is shown below.
Onto the recent Image Capture Asynchronous Ajax FormData Upload Tutorial “Media Capture” web application (but a “spoiler alert” soon (maybe tomorrow) is that we will argue that this can become a mobile application for you mobile users too), today we …
- add megabytes involved in email attachments and numbers of media files involved as emailed to the messaging of the web application … as well as cumulative usage for …
- add an HTML5 progress element
… that we embellish so that you see …
- cumulative megabytes of email attachment data you are creating, encouraging you via the 10mB initial maximum, to Curb Your Enthusiasm
- number of media files attached and/or within a single zip file attachment
… to keep the user better informed of … progress.
Also, we haven’t finished yet, but we think we’re closer to allowing for mixed media selections within any one of …
- changed HTML imagecapture.htm‘s live run (just images) (or, for example, live run (all three categories of “media”)
- changed HTML audiocapture.htm‘s live run
- changed HTML videocapture.htm‘s live run
- changed PHP mailto.php helps out with the email changes
… for you to try yourself, we certainly do hope.
Previous relevant Image Capture Asynchronous Ajax FormData Upload Tutorial is shown below.
Out of the recent Image Capture Ajax FormData Upload Canvas Tutorial HTML’s Javascript Ajax open statement asynchronous (third) argument …
var xhr = new XMLHttpRequest();
xhr.open('post', 'mailto.php', true);
xhr.send(form);
… being true (ie. asynchronous) not able to be changed to false (ie. synchronous) in client Javascript (ie. it has no (serverside) PHP sleep type of function), as it is now deprecated and is dangerous anyway, resulted in 34560 seconds of work per “letter of deprecation” (ie. 2 days) as we pondered, with large images with multiple uploads on an iPhone camera image captured there and then, two choices …
- you can use false (ie. synchronous) Ajax open calls when involving Web Workers, at the clientside, but we decided to …
- make the (serverside) PHP mailto.php do the synchronous “simulation” of what is required to get the job done
Okay, so lots of Ajax transfers are hitting the PHP at once? Is this the go?
Not exactly, as we introduce small delays between xhr.open() calls using the Javascript timer setTimeout() function.
What stops the PHP getting confused?
A few things here. On multiple large transfer scenarios, we force the PHP to use zipfile (email attachment) PHP functionality. That PHP zipfile gets a client IP address component to its name. As each Ajax transfer arrives and is uploaded ready to zip the data up, we flag that zipping has started ahead of us starting zipping. This flagging is recognized when the next Ajax transfer arrives soon after (but delayed that little bit that we introduced at the clientside), and the PHP sleep can be used to simulate a truly synchronous Ajax scenario with a “delays until ready” paradigm.
We didn’t have the best programming day in the world yesterday, and a PHP solution may take you a lot less time, but nonetheless the Web Worker synchronous Ajax solution may be more to your liking.
Like last time, below are …
- changed HTML imagecapture.htm‘s live run (just images) (or, for example, live run (all three categories of “media”)
- changed PHP mailto.php helps out with the email and “synchronous Ajax simulation delayed sleeping” changes
You can also see this play out at WordPress 4.1.1’s Image Capture Asynchronous Ajax FormData Upload Tutorial.
Previous relevant Image Capture Ajax FormData Upload Canvas Tutorial is shown below.
In amongst the media …
- images
- audio
- video
… “talents” of our latest “Media Capture Email” web application, there is another important distinction, for us. It is so much easier to annotate “images” via the HTML(5) canvas element, which you’d have noticed we catered for from the word go, when we started this project, only considering “images”. Talk of the canvas element’s talents are all about …
- annotation
- images … especially in terms of …
- positioning (above)
- transforming (above)
And so, onto yesterday’s Media Capture Ajax FormData Upload Details Tutorial, we’re starting out on our embellishments to functionality via that canvas element sitting there for image display.
Primarily, the area where we need to start here, is with defining onclick and/or onmousedown and/or ontouchdown event logic definition.
The other matter attended to today, and still ongoing, is for multiple image photo captured there and then (on an iPhone for example) issues.
Below are …
- changed HTML imagecapture.htm‘s live run (just images) (or, for example, live run (all three categories of “media”)
- changed PHP mailto.php helps out with the email changes
Previous relevant Media Capture Ajax FormData Upload Details Tutorial is shown below.
We’re trying to improve functionality and usability of the “Media Capture Email” web application we last talked about with Media Multiple Capture Ajax FormData Upload Tutorial yesterday.
Today’s work …
- for web browsers that are not Internet Explorer nor Microsoft Edge we add even more “reveal” logic that makes use of the HTML details/summary elements to unclutter what is cluttered, or, what could get cluttered (via concertinaing up ( ie. [detailsObject].removeAttribute(‘open’) ) what is not the latest media displayed down the bottom of the webpage, that helps keep new images above the fold
- we’ve added our first CSS styling ideas …
<style>
* { font-family: Verdana; }
summary { width:100%; background-color:#f0f0f0; }
#topdmenu { background-color:#e0e0e0; }
hr { height:2px; background-color:orange; }
details { background-color:#d0d0d0; }
#topmostmenu { background-color:#c0c0c0; }
input { background-color:#f0b0d0; }
textarea { background-color:#f7f7f7; }
select { background-color:silver; }
</style>
… to add some colour, and colour coding of logic parts to the webpage, as well as a change of font, to Verdana - adds CC and BCC and Body email functionalities
It’s time to talk about our growing usage of …
<script type='text/javascript'>
document.write([someHtml]);
</script>
… that “plonks” some HTML where it is used in the webpage at the context this Javascript is positioned at. Sound a bit like PHP? Well, a bit, but don’t think you can suddenly do all the operating system and file and database manipulations PHP is capable of just because you use document.write([someHTML]). The use of document.write([someHTML]) has a big advantage, to onload logics for example, though. It can have if/else logic derived from address bar URL arguments and/or Cookie and/or WebStorage and/or navigation object web browser characteristic determinations to change the HTML written on the fly, even before document.body onload event logics.
Below are …
- changed HTML imagecapture.htm‘s live run (just images) (or, for example, live run (all three categories of “media”)
- changed HTML audiocapture.htm‘s live run
- changed HTML videocapture.htm‘s live run
- changed PHP mailto.php helps out with the email changes
… for you to try yourself, we hope.
You can also see this play out at WordPress 4.1.1’s Media Capture Ajax FormData Upload Details Tutorial.
Previous relevant Media Multiple Capture Ajax FormData Upload Tutorial is shown below.
We’re “opening our horizons” or “genericizing our purposes” (but you need a licence for this one … it’s all in the wording) to improve on the recent Image Multiple Capture Ajax FormData Upload Tutorial‘s functionality today. That’ll be why we’ve replaced in the blog posting title (of equal length … snaps to that blogger!) the word “Image” for the more generic term “Media”. “Media”, to us, encompasses …
- images
- audio
- video
… media. Being as all three are concepts that can be attached in emails, and displayed in a webpage, they have more in common than they are different by nature, though it must be said …
- we baulked at displaying non-image “media” in (an HTML5) canvas element
- mimetypes are really only of relevance to non-image “media” elements
- “controls” and “play” functionality is only relevant to non-image “media” elements
Otherwise, though we wrote HTML code components for all three “media” categories, a lot of the code concepts are shared as you can see for yourself with …
- changed HTML imagecapture.htm‘s live run (just images) (or, for example, live run (all three categories of “media”)
- audiocapture.htm‘s live run
- videocapture.htm‘s live run
… means by which, small “media” files of various “categories” above can be combined into email attachments (with all that same “standing order” thoughts of last time), zipped up or not, as the case may be. Typically, email size restrictions are to around or under 10mB of data (ie. less than a minute of video/audio is best).
Previous relevant Image Multiple Capture Ajax FormData Upload Tutorial is shown below.
Please feel free to demand a refund for today’s blog posting whose title is just rearranged title words of yesterday’s Image Capture Ajax FormData Multiple Upload Tutorial but there is a real development here, and it concerns what happens when you execute this web application on a mobile platform.
On a mobile platform, the “capture” attribute of the input element “kicks in”, if you will. So, you may sagely ask, “how does this fit with the ‘multiple’ attribute?”. Excellent question! It doesn’t really, the way we worked it as of yesterday, but today we make amends.
Add one more concept, and we think we can have a pretty good “standing order” type of web application. That “concept” is to add in HTTP Cookie functionality for “intersessional memory” (should the user click the “Remember Me?” checkbox) covering …
- email “to” address
- a “no camera” checkbox to force mobile platforms to represent the menu where images can be either …
- browsed for … or …
- taken there and then … ie. making full use of the “capture” attribute of the HTML input element
- zipfile name
- send when [number] or above ie. if ([number] is) 2 then only upload after the “capture” or “browse picking” of at least 2 images … this is the setting that allows “capture” to live with “multiple” (with or without “zipping”)
- email “subject”
Perhaps you take 2 photos of a particular view each day and send them to a particular email friend with your iPad. Fill out the above once, click the “Remember Me?” to just, from then on, execute the web application, and press the button twice to take two photos twice, and there you are with a behind the scenes emailing of those photos to your friend. That is the sort of functionality we think of as a “standing order”.
Why not try today’s changed HTML imagecapture.htm‘s live run link?
Previous relevant Image Capture Ajax FormData Multiple Upload Tutorial is shown below.
Regular readers at this blog would appreciate the idea that lately we have had a big emphasis on groups of images. There were (the recent) …
- Gimp Guillotine Follow Up Memory Tutorial series which talked about splicing image files from others, and onto other displays of groups of images, including zipping functionality
- One Image Your Own Slideshow Dynamic CSS Filters and Transforms Tutorial took a group of Javascript animated image data and overlayed a layer of HTML iframe functionality to filter and transform that image display … and really recently …
- PHP Exif Image Zip Mystery Game Hints Tutorial pieced together a group of images with geodata (metadata) information into a Mystery Trips Guessing Game … and so …
… we get to our first revisit of Image Capture ideas in yesterday’s Image Capture Ajax FormData Upload Primer Tutorial featuring Ajax FormData functionality, allowing for a …
- one image file at a time …
- image display
- canvas [context].drawImage() display
- upload as email attachment “upload”
… and now, in “onions of the 4th dimension” feel, today, our extensions of functionality allow for “groups of images” (in a new context view) …
- one or more image file(s) at a time …
- image display(s)
- canvas [context].drawImage() display(s)
- upload as email attachment(s) “upload(s)”
… all possible because of the multiple attribute as per …
<input type="file" name="image" accept="image/*" multiple capture>
… that truly manifests itself, in practice, for the user of today’s changed HTML imagecapture.htm‘s live run when they browse for image files, where they can pick more than one image in any one browsing session. In broad brush terms that change in Javascript “client” land means what was (once) a File Object now should be handled in terms of it now being a File Array of Objects. In bold we show how that changed the code of yesterday …
var cfile=[], tops=[], awidth=0, atop=0, c=null, ctx=null, kk=0;
function bp() {
var input = document.querySelector('input[type=file]'); // see Example 4
input.onchange = function () {
var file = input.files[0];
cfile = file;
for (var ii=0; ii<file.length; ii++) {
if (ii == 0) { drawOnCanvas(file); } // see Example 6
if (ii == 0) { upload(file); }
if (eval(1 + eval('' + ii)) == file.length) { whenokdrawOnCanvas(); } // displayAsImage(file); // see Example 7
}
};
var cdate = new Date();
cdatestr=cdate.getFullYear() + ("0" + eval(1 + cdate.getMonth())).slice(-2) + ("0" + cdate.getDate()).slice(-2);
document.getElementById('zipname').placeholder+=' ... imagezip_' + cdatestr + '.zip';
}
function whenokdrawOnCanvas() {
if (kk == cfile.length) {
c = document.querySelector('canvas'), // see Example 4
ctx = c.getContext('2d'),
c.width = awidth;
c.height = Math.abs(atop);
if (atop < 0) {
atop = -atop;
}
for (var jk=0; jk<kk; jk++) {
drawOnCanvas(cfile[jk], tops[jk]);
}
} else {
setTimeout(whenokdrawOnCanvas);
}
}
function drawOnCanvas(file, xtop) {
var reader = new FileReader();
reader.onload = function (e) {
var dataURL = e.target.result, img = new Image();
// c = document.querySelector('canvas'), // see Example 4
// ctx = c.getContext('2d'),
img.onload = function() {
//c.width = img.width;
//c.height = img.height;
ctx.drawImage(img, 0, xtop); // 0
};
img.src = dataURL;
};
reader.readAsDataURL(file);
}
… and …
function upload(file) {
var form = new FormData(),
xhr = new XMLHttpRequest();
if (document.getElementById('to').value.indexOf('@') != -1) {
form.append('to', document.getElementById('to').value);
if (document.getElementById('subject').value != '') {
form.append('subject', document.getElementById('subject').value);
} else {
form.append('subject', 'Image in email');
}
form.append('filename', file[0].name);
}
form.append('image', file[0]);
if (document.getElementById('zipname').value != '') { // new zipfile email attachment input element
form.append('zipname', document.getElementById('zipname').value);
}
if (file.length > 1) {
for (var iii=1; iii<file.length; iii++) {
if (document.getElementById('to').value.indexOf('@') != -1) {
form.append('filename' + iii, file[iii].name);
}
form.append('image' + iii, file[iii]);
}
}
xhr.open('post', 'mailto.php', true);
xhr.send(form);
}
… combines with new (static) HTML/Javascript …
<input onblur="if (this.value.indexOf('@') != -1 && this.value != '@') { document.getElementById('zipname').style.display='inline-block'; } " id="to" name="to" type="text" style="inline-block;" placeholder="Optionally email to" value=""> <input id="subject" name="subject" type="text" style="inline-block;" placeholder="Optional email subject" value=""> <input onclick="if (this.value == '' && this.placeholder.indexOf(' ... ') != -1) { this.value=this.placeholder.split(' ... ')[1]; } " style="display:none;width:30%;" id="zipname" name="zipname" type="text" placeholder="Optional zipfile email attachment name" value="">
… so that where the changes manifest themselves for the supervised and changed PHP mailto.php are that we now have to allow for …
- zipping up (possibly) multiple image(s) into the one zipfile email attachment … or …
- allow for multiple image file email attachments
Below, you can compare new multiple mode (left) to old single choice mode (right) …
New live run | Old live run |
---|---|
Previous relevant Image Capture Ajax FormData Upload Primer Tutorial is shown below.
Were you around and interested in the media capture and upload concepts presented when we discussed this topic with HTML5 Camera API Audio Video Tutorial? Back then, central to the workings of this blog posting’s web application is a perfectly readable, and “obvious” piece of HTML we can show you below …
<form style='display:none;' id='myform' method='POST' enctype='application/x-www-urlencoded' action='//www.rjmprogramming.com.au/HTMLCSS/camera_api.php' target='myiframetwo'>
<input id='mydurl' name='mydurl' type='hidden' value=''></input>
<input id='mymobile' name='mymobile' type='hidden' value=''></input>
<input id='mode' name='mode' value='y'></input>
<input id='fclick' type='submit' value='Email'></input>
</form>
<iframe style='display:none;' id='myiframetwo' name='myiframetwo' src='//www.rjmprogramming.com.au/HTMLCSS/camera_api.php'></iframe>
… and then later some HTML input element to enable image capture was dynamically added …
<input onclick="document.getElementById('aemail').style.display='inline';" type="file" id="take_photograph" accept="image/*">
… the file contents ending up in that mydurl input type=hidden field and back to this same PHP code for “upload” (where there are lots of steps to the “upload” process before it ends up as a web server file, and lots of other uses can be made for that media data ahead of that “total” “upload” … as you see with today’s work as well).
All fairly conventional HTML navigational fare here, and useful, and good.
But … and didn’t you just know there’d be a “but” … today we start down the line of Image Media Capture Uploading that only needs the “hard” (first draft simple) HTML (of today’s new imagecapture.html‘s live run) …
<input type="file" name="image" accept="image/*" capture>
… and then, thanks to the inspiration from https://www.w3.org/TR/html-media-capture/ our code involves …
- document.body onload (<body onload=’bp();’ style=’background-color:lightblue;’>) logic …
function bp() {
var input = document.querySelector('input[type=file]'); // see Example 4
input.onchange = function () {
var file = input.files[0];
upload(file);
drawOnCanvas(file); // see Example 6
displayAsImage(file); // see Example 7
};
}
- to link to the Javascript Ajax upload(file) function, featuring the FormData object code …
function upload(file) {
var form = new FormData(),
xhr = new XMLHttpRequest();
if (document.getElementById('to').value.indexOf('@') != -1) {
form.append('to', document.getElementById('to').value);
if (document.getElementById('subject').value != '') {
form.append('subject', document.getElementById('subject').value);
} else {
form.append('subject', 'Image in email');
}
form.append('filename', file.name);
}
form.append('image', file);
xhr.open('post', 'mailto.php', true);
xhr.send(form);
}
- as the link to the serverside (new) PHP uploader functionality of mailto.php
You may want to say “so what”. It’s true that this approach is still based on an HTML form, just that it is dynamically created. Yes, that’s true, but it is also true that the onset of mobile applications spurred that increasing use of Ajax techniques of “navigational messaging”, so to start using these techniques means more that you are “going with the flow”, and be able to adapt to these more modern approaches to these media uploading ideas.
Previous relevant HTML5 Camera API Audio Video Tutorial is shown below.
Yesterday we started down the line of examining the Camera API in HTML5 with HTML5 Camera API Primer Tutorial as shown below.
There we thought of the “Camera” being a camera of “Images”, but most modern smart phones or tablets have a Camera app that can capture …
- Video
- Audio
- Image
… media sources.
These two new media sources “Audio” and “Video” above need the intervention of a PHP server side emailer functionality in order to send out HTML emails with data URI “src=” HTML elements for these two types of media data.
How do we work this for the user using this web application? We allow the “media sources” above be part of an HTML “select” dropdown and separate the choices in the predominantly Javascript DOM “client feeling” code via the use of “document.URL” logic control (of Javascript DOM document.write() method) as per this …
<script type='text/javascript'>
if (document.URL.toLowerCase().indexOf('video') != -1) {
// Video specific logic ... eg. ...
document.write('<input onclick="document.getElementById(' + "'" + 'aemail' + "'" + ').style.display=' + "'" + 'inline' + "'" + ';" type="file" id="take_photograph" accept="video/*">');
} else if (document.URL.toLowerCase().indexOf('audio') != -1) {
// Audio specific logic ... eg. ...
document.write('<input onclick="document.getElementById(' + "'" + 'aemail' + "'" + ').style.display=' + "'" + 'inline' + "'" + ';" type="file" id="take_photograph" accept="audio/*">');
} else {
// Image specific logic ... eg. ...
document.write('<input onclick="document.getElementById(' + "'" + 'aemail' + "'" + ').style.display=' + "'" + 'inline' + "'" + ';" type="file" id="take_photograph" accept="image/*">');
}
</script>
… skeletal HTML code design approach. This approach is only an easy thing to implement when it is driven in its logic by something that exists intact before the document.body onload event, that being document.URL that equates to the web browser address bar URL.
So this led us to the HTML parent web application you could call camera_api.htm that you can try with this live run link, and that changed in this way to be able to process those newly introduced Audio and Video media sources that get emailed via our new PHP server side emailer camera_api.php but bear in mind that long running Audio and/or Video media captures are not welcome. Otherwise, please feel free to try out this web application working with your Camera app.
Previous relevant HTML5 Camera API Primer Tutorial is shown below.
Okay, so more HTML5 awaits, and we start down the track today with some research and development regarding the Camera API, and point you towards a few unbelievably great resources that have been put before us …
- robnyman/robnyman.github.com … we got onto, via …
- Camera API introduction … via HTML5 – Web developer guides | MDN … and got helped with blob to data URI conversion ideas from Convert Image to Data URI with JavaScript
… and this led us to this proof of concept web application you could call camera_api.html that you can try with this live run link. The fly in the ointment, however, is browser and platform compatibility here. The web application …
- asks the user for permission to use the camera to take photographs with the device’s camera … and/or
- asks the user to point to a local (photograph) file … and then we …
- interface either of these photographic data source and funnel it through email (client) functionality, optionally
Browser and platform wise, that first bit of functionality above is only supported, notionally, on Firefox and Google Chrome web browsers on Android, though we also found it worked on an (iOS) iPad. Most browsers and platforms work with the latter two features above.
So what are the Javascript syntax highlights of making the first two of the list above … ie. the Camera API (in HTML5) … to work. You need …
- capturing the data via the device camera, via
<input onclick="document.getElementById('aemail').style.display='inline';" type="file" id="take_photograph" accept="image/*">
- use of as createObjectURL method as per
var imgURL = window.URL.createObjectURL(file);
- or alternatively, the use of the FileReader object as per
var fileReader = new FileReader();
Try it out yourself to get this web application into context.
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.
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.