8 Jun 2017
Manipulate Mobile Camera and Album by JavaScript

In the last blog, I introduced my practice with gyro sensor and touch of mobile, remotely connecting to the web application of Forge Viewer. As promised, I am now introducing the way to access mobile camera and album by native JavaScript. This would be useful for a typical scenario of construction industry: the worker checks issues on the field, takes a photo, and submits to the administration platform.
This is also very straightforward. We simply define an DOM element of HTML as a File type, specifying it to accept image and camera.
<div> | |
<input type="file" id = "mobilephoto" accept="image/*" capture="camera" > | |
<img class = "mythumbnail" id="outImage"/> | |
</div> | |
<div> | |
<input type="button" id="btnSubmit" class="btn btn-primary" value="Submit" /> | |
</div> |
The web page would look like :
[[{"fid":"2070","view_mode":"wysiwyg","type":"media","attributes":{"height":"400","width":"225","class":"media-element file-wysiwyg"}}]]
On PC, clicking this file button, it will be just a common functionality of choosing file, while on the mobile, it will take you to access existing album or take a new photo.
[[{"fid":"2069","view_mode":"wysiwyg","type":"media","attributes":{"height":"300","width":"169","class":"media-element file-wysiwyg"}}]]
For some small images, we could simply submit the image stream (blob). I used a class JIC to compress the source stream, in order to relieve the internet traffic when transferring. If it is a large image, it is best to upload the source image file.
//compress source image blob | |
//from http://www.programering.com/a/MDOxAzMwATY.html | |
var jic = { | |
compress: function(source_img_obj, quality, output_format){ | |
var mime_type = "image/jpeg"; | |
if(output_format!=undefined && output_format=="png"){ | |
mime_type = "image/png"; | |
} | |
var cvs = document.createElement('canvas'); | |
cvs.width = source_img_obj.naturalWidth; | |
cvs.height = source_img_obj.naturalHeight; | |
var ctx = cvs.getContext("2d").drawImage(source_img_obj, 0, 0); | |
var newImageData = cvs.toDataURL(mime_type, quality/100); | |
var result_image_obj = new Image(); | |
result_image_obj.src = newImageData; | |
return result_image_obj; | |
} | |
} | |
$(document).ready (function () { | |
$('#btnSubmit').click(function (evt) { | |
//get source image | |
var blob = document.getElementById('outImage').src ; | |
var img = new Image(); | |
img.src = blob; | |
//compress the stream | |
var imgdata = jic.compress(img,1).src; | |
var toUpload = {blob:imgdata}; | |
//upload the blog to server | |
$.ajax ({ | |
url: 'http://' + window.location.host + '/ForgeRoute/setImage', | |
type: 'post', | |
data: toUpload, | |
dataType:'json' | |
}).done (function (data) { | |
console.log('upload image blob done!'); | |
}).fail (function (xhr, ajaxOptions, thrownError) { | |
console.log('upload image blob failed!'); | |
}) ; | |
}); | |
document.getElementById('mobilephoto').onchange = function (evt) { | |
var tgt = evt.target || window.event.srcElement, | |
files = tgt.files; | |
// FileReader support | |
if (FileReader && files && files.length) { | |
var fr = new FileReader(); | |
fr.onload = function () { | |
//display the image in the image box | |
document.getElementById('outImage').src = fr.result; | |
} | |
fr.readAsDataURL(files[0]); | |
} | |
else { | |
// Not supported | |
console.log('not supported!'); | |
} | |
} | |
}) ; | |
[[{"fid":"2071","view_mode":"wysiwyg","type":"media","attributes":{"height":"400","width":"200","class":"media-element file-wysiwyg"}}]]
In the web application of Forge Viewer, my demo creates a panel which consumes the image blob from the server.
[[{"fid":"2072","view_mode":"wysiwyg","type":"media","attributes":{"height":"400","width":"611","class":"media-element file-wysiwyg"}}]]
The whole demo codes is available at: https://github.com/xiaodongliang/Forge-Test-Field-Mobile-Camera