(function(window){
var _userMedia;
function FlashError(){
var temp=Error.apply(this, arguments);
temp.name=this.name="FlashError";
this.stack=temp.stack;
this.message=temp.message;
}
function WebcamError(){
var temp=Error.apply(this, arguments);
temp.name=this.name="WebcamError";
this.stack=temp.stack;
this.message=temp.message;
}
IntermediateInheritor=function(){};
IntermediateInheritor.prototype=Error.prototype;
FlashError.prototype=new IntermediateInheritor();
WebcamError.prototype=new IntermediateInheritor();
var Webcam={
version: '1.0.23',
protocol: location.protocol.match(/https/i) ? 'https':'http',
loaded: false,
live: false,
userMedia: true,
iOS: /iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,
params: {
width: 0,
height: 0,
dest_width: 0,
dest_height: 0,
image_format: 'jpeg',
jpeg_quality: 90,
enable_flash: true,
force_flash: false,
flip_horiz: false,
fps: 30,
upload_name: 'webcam',
constraints: null,
swfURL: '',
flashNotDetectedText: 'ERROR: No Adobe Flash Player detected.  Webcam.js relies on Flash for browsers that do not support getUserMedia (like yours).',
noInterfaceFoundText: 'No supported webcam interface found.',
unfreeze_snap: true,
iosPlaceholderText: 'Click here to open camera.',
user_callback: null,
user_canvas: null
},
errors: {
FlashError: FlashError,
WebcamError: WebcamError
},
hooks: {},
init: function(){
var self=this;
this.mediaDevices=(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia) ?
navigator.mediaDevices:((navigator.mozGetUserMedia||navigator.webkitGetUserMedia) ? {
getUserMedia: function(c){
return new Promise(function(y, n){
(navigator.mozGetUserMedia ||
navigator.webkitGetUserMedia).call(navigator, c, y, n);
});
}}:null);
window.URL=window.URL||window.webkitURL||window.mozURL||window.msURL;
this.userMedia=this.userMedia&&!!this.mediaDevices&&!!window.URL;
if(this.iOS){
this.userMedia=null;
}
if(navigator.userAgent.match(/Firefox\D+(\d+)/)){
if(parseInt(RegExp.$1, 10) < 21) this.userMedia=null;
}
if(this.userMedia){
window.addEventListener('beforeunload', function(event){
self.reset();
});
}},
exifOrientation: function(binFile){
var dataView=new DataView(binFile);
if((dataView.getUint8(0)!=0xFF)||(dataView.getUint8(1)!=0xD8)){
console.log('Not a valid JPEG file');
return 0;
}
var offset=2;
var marker=null;
while (offset < binFile.byteLength){
if(dataView.getUint8(offset)!=0xFF){
console.log('Not a valid marker at offset ' + offset + ', found: ' + dataView.getUint8(offset));
return 0;
}
marker=dataView.getUint8(offset + 1);
if(marker==225){
offset +=4;
var str="";
for (n=0; n < 4; n++){
str +=String.fromCharCode(dataView.getUint8(offset+n));
}
if(str!='Exif'){
console.log('Not valid EXIF data found');
return 0;
}
offset +=6;
var bigEnd=null;
if(dataView.getUint16(offset)==0x4949){
bigEnd=false;
}else if(dataView.getUint16(offset)==0x4D4D){
bigEnd=true;
}else{
console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
return 0;
}
if(dataView.getUint16(offset+2, !bigEnd)!=0x002A){
console.log("Not valid TIFF data! (no 0x002A)");
return 0;
}
var firstIFDOffset=dataView.getUint32(offset+4, !bigEnd);
if(firstIFDOffset < 0x00000008){
console.log("Not valid TIFF data! (First offset less than 8)", dataView.getUint32(offset+4, !bigEnd));
return 0;
}
var dataStart=offset + firstIFDOffset;
var entries=dataView.getUint16(dataStart, !bigEnd);
for (var i=0; i<entries; i++){
var entryOffset=dataStart + i*12 + 2;
if(dataView.getUint16(entryOffset, !bigEnd)==0x0112){
var valueType=dataView.getUint16(entryOffset+2, !bigEnd);
var numValues=dataView.getUint32(entryOffset+4, !bigEnd);
if(valueType!=3&&numValues!=1){
console.log('Invalid EXIF orientation value type ('+valueType+') or count ('+numValues+')');
return 0;
}
var value=dataView.getUint16(entryOffset + 8, !bigEnd);
if(value < 1||value > 8){
console.log('Invalid EXIF orientation value ('+value+')');
return 0;
}
return value;
}}
}else{
offset +=2+dataView.getUint16(offset+2);
}}
return 0;
},
fixOrientation: function(origObjURL, orientation, targetImg){
var img=new Image();
img.addEventListener('load', function(event){
var canvas=document.createElement('canvas');
var ctx=canvas.getContext('2d');
if(orientation < 5){
canvas.width=img.width;
canvas.height=img.height;
}else{
canvas.width=img.height;
canvas.height=img.width;
}
switch (orientation){
case 2: ctx.transform(-1, 0, 0, 1, img.width, 0); break;
case 3: ctx.transform(-1, 0, 0, -1, img.width, img.height); break;
case 4: ctx.transform(1, 0, 0, -1, 0, img.height); break;
case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
case 6: ctx.transform(0, 1, -1, 0, img.height , 0); break;
case 7: ctx.transform(0, -1, -1, 0, img.height, img.width); break;
case 8: ctx.transform(0, -1, 1, 0, 0, img.width); break;
}
ctx.drawImage(img, 0, 0);
targetImg.src=canvas.toDataURL();
}, false);
img.src=origObjURL;
},
attach: function(elem){
if(typeof(elem)=='string'){
elem=document.getElementById(elem)||document.querySelector(elem);
}
if(!elem){
return this.dispatch('error', new WebcamError("Could not locate DOM element to attach to."));
}
this.container=elem;
elem.innerHTML='';
var peg=document.createElement('div');
elem.appendChild(peg);
this.peg=peg;
if(!this.params.width) this.params.width=elem.offsetWidth;
if(!this.params.height) this.params.height=elem.offsetHeight;
if(!this.params.width||!this.params.height){
return this.dispatch('error', new WebcamError("No width and/or height for webcam.  Please call set() first, or attach to a visible element."));
}
if(!this.params.dest_width) this.params.dest_width=this.params.width;
if(!this.params.dest_height) this.params.dest_height=this.params.height;
this.userMedia=_userMedia===undefined ? this.userMedia:_userMedia;
if(this.params.force_flash){
_userMedia=this.userMedia;
this.userMedia=null;
}
if(typeof this.params.fps!=="number") this.params.fps=30;
var scaleX=this.params.width / this.params.dest_width;
var scaleY=this.params.height / this.params.dest_height;
if(this.userMedia){
var video=document.createElement('video');
video.setAttribute('autoplay', 'autoplay');
video.style.width='' + this.params.dest_width + 'px';
video.style.height='' + this.params.dest_height + 'px';
if((scaleX!=1.0)||(scaleY!=1.0)){
elem.style.overflow='hidden';
video.style.webkitTransformOrigin='0px 0px';
video.style.mozTransformOrigin='0px 0px';
video.style.msTransformOrigin='0px 0px';
video.style.oTransformOrigin='0px 0px';
video.style.transformOrigin='0px 0px';
video.style.webkitTransform='scaleX('+scaleX+') scaleY('+scaleY+')';
video.style.mozTransform='scaleX('+scaleX+') scaleY('+scaleY+')';
video.style.msTransform='scaleX('+scaleX+') scaleY('+scaleY+')';
video.style.oTransform='scaleX('+scaleX+') scaleY('+scaleY+')';
video.style.transform='scaleX('+scaleX+') scaleY('+scaleY+')';
}
elem.appendChild(video);
this.video=video;
var self=this;
this.mediaDevices.getUserMedia({
"audio": false,
"video": this.params.constraints||{
mandatory: {
minWidth: this.params.dest_width,
minHeight: this.params.dest_height
}}
})
.then(function(stream){
video.onloadedmetadata=function(e){
self.stream=stream;
self.loaded=true;
self.live=true;
self.dispatch('load');
self.dispatch('live');
self.flip();
};
video.src=window.URL.createObjectURL(stream)||stream;
})
.catch(function(err){
if(self.params.enable_flash&&self.detectFlash()){
setTimeout(function(){ self.params.force_flash=1; self.attach(elem); }, 1);
}else{
self.dispatch('error', err);
}});
}
else if(this.iOS){
var div=document.createElement('div');
div.id=this.container.id+'-ios_div';
div.className='webcamjs-ios-placeholder';
div.style.width='' + this.params.width + 'px';
div.style.height='' + this.params.height + 'px';
div.style.textAlign='center';
div.style.display='table-cell';
div.style.verticalAlign='middle';
div.style.backgroundRepeat='no-repeat';
div.style.backgroundSize='contain';
div.style.backgroundPosition='center';
var span=document.createElement('span');
span.className='webcamjs-ios-text';
span.innerHTML=this.params.iosPlaceholderText;
div.appendChild(span);
var img=document.createElement('img');
img.id=this.container.id+'-ios_img';
img.style.width='' + this.params.dest_width + 'px';
img.style.height='' + this.params.dest_height + 'px';
img.style.display='none';
div.appendChild(img);
var input=document.createElement('input');
input.id=this.container.id+'-ios_input';
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.setAttribute('capture', 'camera');
var self=this;
var params=this.params;
input.addEventListener('change', function(event){
if(event.target.files.length > 0&&event.target.files[0].type.indexOf('image/')==0){
var objURL=URL.createObjectURL(event.target.files[0]);
var image=new Image();
image.addEventListener('load', function(event){
var canvas=document.createElement('canvas');
canvas.width=params.dest_width;
canvas.height=params.dest_height;
var ctx=canvas.getContext('2d');
ratio=Math.min(image.width / params.dest_width, image.height / params.dest_height);
var sw=params.dest_width * ratio;
var sh=params.dest_height * ratio;
var sx=(image.width - sw) / 2;
var sy=(image.height - sh) / 2;
ctx.drawImage(image, sx, sy, sw, sh, 0, 0, params.dest_width, params.dest_height);
var dataURL=canvas.toDataURL();
img.src=dataURL;
div.style.backgroundImage="url('"+dataURL+"')";
}, false);
var fileReader=new FileReader();
fileReader.addEventListener('load', function(e){
var orientation=self.exifOrientation(e.target.result);
if(orientation > 1){
self.fixOrientation(objURL, orientation, image);
}else{
image.src=objURL;
}}, false);
var http=new XMLHttpRequest();
http.open("GET", objURL, true);
http.responseType="blob";
http.onload=function(e){
if(this.status==200||this.status===0){
fileReader.readAsArrayBuffer(this.response);
}};
http.send();
}}, false);
input.style.display='none';
jQuery(elem).closest('.ci_editor').append(input);
/**div.addEventListener('click', function(event){
if(params.user_callback){
self.snap(params.user_callback, params.user_canvas);
}else{
input.style.display='block';
input.focus();
input.click();
input.style.display='none';
}}, false);**/
div.style.display='none';
jQuery(elem).closest('.ci_editor').append(div);
this.loaded=true;
this.live=true;
if(params.user_callback){
self.snap(params.user_callback, params.user_canvas);
}else{
input.style.display='block';
input.focus();
input.click();
input.style.display='none';
}}
else if(this.params.enable_flash&&this.detectFlash()){
window.Webcam=Webcam;
var div=document.createElement('div');
div.innerHTML=this.getSWFHTML();
elem.appendChild(div);
}else{
this.dispatch('error', new WebcamError(this.params.noInterfaceFoundText));
}
if(this.params.crop_width&&this.params.crop_height){
var scaled_crop_width=Math.floor(this.params.crop_width * scaleX);
var scaled_crop_height=Math.floor(this.params.crop_height * scaleY);
elem.style.width='' + scaled_crop_width + 'px';
elem.style.height='' + scaled_crop_height + 'px';
elem.style.overflow='hidden';
elem.scrollLeft=Math.floor((this.params.width / 2) - (scaled_crop_width / 2));
elem.scrollTop=Math.floor((this.params.height / 2) - (scaled_crop_height / 2));
}else{
elem.style.width='' + this.params.width + 'px';
elem.style.height='' + this.params.height + 'px';
}},
reset: function(){
if(this.preview_active) this.unfreeze();
this.unflip();
if(this.userMedia){
if(this.stream){
if(this.stream.getVideoTracks){
var tracks=this.stream.getVideoTracks();
if(tracks&&tracks[0]&&tracks[0].stop) tracks[0].stop();
}
else if(this.stream.stop){
this.stream.stop();
}}
delete this.stream;
delete this.video;
}
if((this.userMedia!==true)&&this.loaded&&!this.iOS){
var movie=this.getMovie();
if(movie&&movie._releaseCamera) movie._releaseCamera();
}
if(this.container){
this.container.innerHTML='';
delete this.container;
}
this.loaded=false;
this.live=false;
},
set: function(){
if(arguments.length==1){
for (var key in arguments[0]){
this.params[key]=arguments[0][key];
}}else{
this.params[ arguments[0] ]=arguments[1];
}},
on: function(name, callback){
name=name.replace(/^on/i, '').toLowerCase();
if(!this.hooks[name]) this.hooks[name]=[];
this.hooks[name].push(callback);
},
off: function(name, callback){
name=name.replace(/^on/i, '').toLowerCase();
if(this.hooks[name]){
if(callback){
var idx=this.hooks[name].indexOf(callback);
if(idx > -1) this.hooks[name].splice(idx, 1);
}else{
this.hooks[name]=[];
}}
},
dispatch: function(){
var name=arguments[0].replace(/^on/i, '').toLowerCase();
var args=Array.prototype.slice.call(arguments, 1);
if(this.hooks[name]&&this.hooks[name].length){
for (var idx=0, len=this.hooks[name].length; idx < len; idx++){
var hook=this.hooks[name][idx];
if(typeof(hook)=='function'){
hook.apply(this, args);
}
else if((typeof(hook)=='object')&&(hook.length==2)){
hook[0][hook[1]].apply(hook[0], args);
}
else if(window[hook]){
window[ hook ].apply(window, args);
}}
return true;
}
else if(name=='error'){
if((args[0] instanceof FlashError)||(args[0] instanceof WebcamError)){
message=args[0].message;
}else{
message="Could not access webcam: " + args[0].name + ": " +
args[0].message + " " + args[0].toString();
}
alert("Webcam.js Error: " + message);
}
return false;
},
setSWFLocation: function(value){
this.set('swfURL', value);
},
detectFlash: function(){
var SHOCKWAVE_FLASH="Shockwave Flash",
SHOCKWAVE_FLASH_AX="ShockwaveFlash.ShockwaveFlash",
FLASH_MIME_TYPE="application/x-shockwave-flash",
win=window,
nav=navigator,
hasFlash=false;
if(typeof nav.plugins!=="undefined"&&typeof nav.plugins[SHOCKWAVE_FLASH]==="object"){
var desc=nav.plugins[SHOCKWAVE_FLASH].description;
if(desc&&(typeof nav.mimeTypes!=="undefined"&&nav.mimeTypes[FLASH_MIME_TYPE]&&nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)){
hasFlash=true;
}}
else if(typeof win.ActiveXObject!=="undefined"){
try {
var ax=new ActiveXObject(SHOCKWAVE_FLASH_AX);
if(ax){
var ver=ax.GetVariable("$version");
if(ver) hasFlash=true;
}}
catch (e){;}}
return hasFlash;
},
getSWFHTML: function(){
var html='',
swfURL=this.params.swfURL;
if(location.protocol.match(/file/)){
this.dispatch('error', new FlashError("Flash does not work from local disk.  Please run from a web server."));
return '<h3 style="color:red">ERROR: the Webcam.js Flash fallback does not work from local disk.  Please run it from a web server.</h3>';
}
if(!this.detectFlash()){
this.dispatch('error', new FlashError("Adobe Flash Player not found.  Please install from get.adobe.com/flashplayer and try again."));
return '<h3 style="color:red">' + this.params.flashNotDetectedText + '</h3>';
}
if(!swfURL){
var base_url='';
var scpts=document.getElementsByTagName('script');
for (var idx=0, len=scpts.length; idx < len; idx++){
var src=scpts[idx].getAttribute('src');
if(src&&src.match(/\/webcam(\.min)?\.js/)){
base_url=src.replace(/\/webcam(\.min)?\.js.*$/, '');
idx=len;
}}
if(base_url) swfURL=base_url + '/webcam.swf';
else swfURL='webcam.swf';
}
if(window.localStorage&&!localStorage.getItem('visited')){
this.params.new_user=1;
localStorage.setItem('visited', 1);
}
var flashvars='';
for (var key in this.params){
if(flashvars) flashvars +='&';
flashvars +=key + '=' + escape(this.params[key]);
}
html +='<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" type="application/x-shockwave-flash" codebase="'+this.protocol+'://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+this.params.width+'" height="'+this.params.height+'" id="webcam_movie_obj" align="middle"><param name="wmode" value="opaque" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+swfURL+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><embed id="webcam_movie_embed" src="'+swfURL+'" wmode="opaque" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+this.params.width+'" height="'+this.params.height+'" name="webcam_movie_embed" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'"></embed></object>';
return html;
},
getMovie: function(){
if(!this.loaded) return this.dispatch('error', new FlashError("Flash Movie is not loaded yet"));
var movie=document.getElementById('webcam_movie_obj');
if(!movie||!movie._snap) movie=document.getElementById('webcam_movie_embed');
if(!movie) this.dispatch('error', new FlashError("Cannot locate Flash movie in DOM"));
return movie;
},
freeze: function(){
var self=this;
var params=this.params;
if(this.preview_active) this.unfreeze();
var scaleX=this.params.width / this.params.dest_width;
var scaleY=this.params.height / this.params.dest_height;
this.unflip();
var final_width=params.crop_width||params.dest_width;
var final_height=params.crop_height||params.dest_height;
var preview_canvas=document.createElement('canvas');
preview_canvas.width=final_width;
preview_canvas.height=final_height;
var preview_context=preview_canvas.getContext('2d');
this.preview_canvas=preview_canvas;
this.preview_context=preview_context;
if((scaleX!=1.0)||(scaleY!=1.0)){
preview_canvas.style.webkitTransformOrigin='0px 0px';
preview_canvas.style.mozTransformOrigin='0px 0px';
preview_canvas.style.msTransformOrigin='0px 0px';
preview_canvas.style.oTransformOrigin='0px 0px';
preview_canvas.style.transformOrigin='0px 0px';
preview_canvas.style.webkitTransform='scaleX('+scaleX+') scaleY('+scaleY+')';
preview_canvas.style.mozTransform='scaleX('+scaleX+') scaleY('+scaleY+')';
preview_canvas.style.msTransform='scaleX('+scaleX+') scaleY('+scaleY+')';
preview_canvas.style.oTransform='scaleX('+scaleX+') scaleY('+scaleY+')';
preview_canvas.style.transform='scaleX('+scaleX+') scaleY('+scaleY+')';
}
this.snap(function(){
preview_canvas.style.position='relative';
preview_canvas.style.left='' + self.container.scrollLeft + 'px';
preview_canvas.style.top='' + self.container.scrollTop + 'px';
self.container.insertBefore(preview_canvas, self.peg);
self.container.style.overflow='hidden';
self.preview_active=true;
}, preview_canvas);
},
unfreeze: function(){
if(this.preview_active){
this.container.removeChild(this.preview_canvas);
delete this.preview_context;
delete this.preview_canvas;
this.preview_active=false;
this.flip();
}},
flip: function(){
if(this.params.flip_horiz){
var sty=this.container.style;
sty.webkitTransform='scaleX(-1)';
sty.mozTransform='scaleX(-1)';
sty.msTransform='scaleX(-1)';
sty.oTransform='scaleX(-1)';
sty.transform='scaleX(-1)';
sty.filter='FlipH';
sty.msFilter='FlipH';
}},
unflip: function(){
if(this.params.flip_horiz){
var sty=this.container.style;
sty.webkitTransform='scaleX(1)';
sty.mozTransform='scaleX(1)';
sty.msTransform='scaleX(1)';
sty.oTransform='scaleX(1)';
sty.transform='scaleX(1)';
sty.filter='';
sty.msFilter='';
}},
savePreview: function(user_callback, user_canvas){
var params=this.params;
var canvas=this.preview_canvas;
var context=this.preview_context;
if(user_canvas){
var user_context=user_canvas.getContext('2d');
user_context.drawImage(canvas, 0, 0);
}
user_callback(
user_canvas ? null:canvas.toDataURL('image/' + params.image_format, params.jpeg_quality / 100),
canvas,
context
);
if(this.params.unfreeze_snap) this.unfreeze();
},
snap: function(user_callback, user_canvas){
if(!user_callback) user_callback=this.params.user_callback;
if(!user_canvas) user_canvas=this.params.user_canvas;
var self=this;
var params=this.params;
if(!this.loaded) return this.dispatch('error', new WebcamError("Webcam is not loaded yet"));
if(!user_callback) return this.dispatch('error', new WebcamError("Please provide a callback function or canvas to snap()"));
if(this.preview_active){
this.savePreview(user_callback, user_canvas);
return null;
}
var canvas=document.createElement('canvas');
canvas.width=this.params.dest_width;
canvas.height=this.params.dest_height;
var context=canvas.getContext('2d');
if(this.params.flip_horiz){
context.translate(params.dest_width, 0);
context.scale(-1, 1);
}
var func=function(){
if(this.src&&this.width&&this.height){
context.drawImage(this, 0, 0, params.dest_width, params.dest_height);
}
if(params.crop_width&&params.crop_height){
var crop_canvas=document.createElement('canvas');
crop_canvas.width=params.crop_width;
crop_canvas.height=params.crop_height;
var crop_context=crop_canvas.getContext('2d');
crop_context.drawImage(canvas,
Math.floor((params.dest_width / 2) - (params.crop_width / 2)),
Math.floor((params.dest_height / 2) - (params.crop_height / 2)),
params.crop_width,
params.crop_height,
0,
0,
params.crop_width,
params.crop_height
);
context=crop_context;
canvas=crop_canvas;
}
if(user_canvas){
var user_context=user_canvas.getContext('2d');
user_context.drawImage(canvas, 0, 0);
}
user_callback(
user_canvas ? null:canvas.toDataURL('image/' + params.image_format, params.jpeg_quality / 100),
canvas,
context
);
};
if(this.userMedia){
context.drawImage(this.video, 0, 0, this.params.dest_width, this.params.dest_height);
func();
}
else if(this.iOS){
var div=document.getElementById(this.container.id+'-ios_div');
var img=document.getElementById(this.container.id+'-ios_img');
var input=document.getElementById(this.container.id+'-ios_input');
iFunc=function(event){
func.call(img);
img.removeEventListener('load', iFunc);
div.style.backgroundImage='none';
img.removeAttribute('src');
input.value=null;
};
if(!input.value){
img.addEventListener('load', iFunc);
input.style.display='block';
input.focus();
input.click();
input.style.display='none';
}else{
iFunc(null);
}}else{
var raw_data=this.getMovie()._snap();
var img=new Image();
img.onload=func;
img.src='data:image/'+this.params.image_format+';base64,' + raw_data;
}
return null;
},
configure: function(panel){
if(!panel) panel="camera";
this.getMovie()._configure(panel);
},
flashNotify: function(type, msg){
switch (type){
case 'flashLoadComplete':
this.loaded=true;
this.dispatch('load');
break;
case 'cameraLive':
this.live=true;
this.dispatch('live');
break;
case 'error':
this.dispatch('error', new FlashError(msg));
break;
default:
break;
}},
b64ToUint6: function(nChr){
return nChr > 64&&nChr < 91 ? nChr - 65
: nChr > 96&&nChr < 123 ? nChr - 71
: nChr > 47&&nChr < 58 ? nChr + 4
: nChr===43 ? 62:nChr===47 ? 63:0;
},
base64DecToArr: function(sBase64, nBlocksSize){
var sB64Enc=sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen=sB64Enc.length,
nOutLen=nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize:nInLen * 3 + 1 >> 2,
taBytes=new Uint8Array(nOutLen);
for (var nMod3, nMod4, nUint24=0, nOutIdx=0, nInIdx=0; nInIdx < nInLen; nInIdx++){
nMod4=nInIdx & 3;
nUint24 |=this.b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
if(nMod4===3||nInLen - nInIdx===1){
for (nMod3=0; nMod3 < 3&&nOutIdx < nOutLen; nMod3++, nOutIdx++){
taBytes[nOutIdx]=nUint24 >>> (16 >>> nMod3 & 24) & 255;
}
nUint24=0;
}}
return taBytes;
},
upload: function(image_data_uri, target_url, callback){
var form_elem_name=this.params.upload_name||'webcam';
var image_fmt='';
if(image_data_uri.match(/^data\:image\/(\w+)/))
image_fmt=RegExp.$1;
else
throw "Cannot locate image format in Data URI";
var raw_image_data=image_data_uri.replace(/^data\:image\/\w+\;base64\,/, '');
var http=new XMLHttpRequest();
http.open("POST", target_url, true);
if(http.upload&&http.upload.addEventListener){
http.upload.addEventListener('progress', function(e){
if(e.lengthComputable){
var progress=e.loaded / e.total;
Webcam.dispatch('uploadProgress', progress, e);
}}, false);
}
var self=this;
http.onload=function(){
if(callback) callback.apply(self, [http.status, http.responseText, http.statusText]);
Webcam.dispatch('uploadComplete', http.status, http.responseText, http.statusText);
};
var blob=new Blob([ this.base64DecToArr(raw_image_data) ], {type: 'image/'+image_fmt});
var form=new FormData();
form.append(form_elem_name, blob, form_elem_name+"."+image_fmt.replace(/e/, ''));
http.send(form);
}};
Webcam.init();
if(typeof define==='function'&&define.amd){
define(function(){ return Webcam; });
}
else if(typeof module==='object'&&module.exports){
module.exports=Webcam;
}else{
window.Webcam=Webcam;
}}(window));