前几个月闲得无聊写得一段代码,没想最近刚好用上了,在硬盘里翻了半天找回来,还没好好整理直接用上了
手机用户拍照上传的图片一般都在1M 到4M 之间,如果只是用作头像尺寸就可以缩小很多,1M甚至几M的图转换成几百K。
<!doctype html> <html> <head> <title>test</title> <script src="js/zepto-master/src/zepto.min.js"></script> <script>
/*****
by cnblogs.com/ecalf
**/
var uploadImg = (function($){ function fileUpLoader(config){ if(typeof(config.field)=='string'){//input type=file config.field = document.getElementById(config.field); } if(typeof(config.viewPane)=='string'){//预览图 config.viewPane = document.getElementById(config.viewPane); } if(typeof(config.uploadBtn)=='string'){//上传按钮 config.uploadBtn = document.getElementById(config.uploadBtn); } this.afterSelectFile = config.afterSelectFile||function(){}; this.maxSize = config.maxSize==undefined?4194304:(config.maxSize||0);//maxSize 0 不限制大小 this.field = config.field; this.viewPane = config.viewPane; this.uploadBtn = config.uploadBtn; if(config.uploadUrl){ this.uploadUrl = config.uploadUrl; } if(typeof(config.afterUpload)=='function'){ this.afterUpload = config.afterUpload; } if(Object(config.extParams)===config.extParams){ this.extParams = config.extParams; } this.init(); } fileUpLoader.prototype = { init:function(){ this.domEvents(); console.log('uploadfile init'); }, domEvents:function(){ var host = this; if(host.field&&host.afterSelectFile){ $(host.field).on("change",function(e){ host.afterSelectFile&&host.afterSelectFile(this); }); } if(host.uploadBtn){ $(host.uploadBtn).on('click',function(){ host.upload(); }); } }, imgToDataURL:function(img,type,typecallback,frag){ type = type||'image/png';
var databack={ status:true, dataURL:'', callback:callback, resolve:function(){ this.callback(this.dataURL); } } var trans = function(pic){//canvas.toDataURL,context.getImageData 不能读取跨域图片 pic.crossOrigin = "*"; var cvs = document.createElement("canvas"); document.body.appendChild(cvs); var ctx = cvs.getContext('2d'); cvs.width = pic.width; cvs.height = pic.height; console.log('img size:',pic.width+'px',pic.height+'px'); ctx.drawImage(pic,0,0,pic.width,pic.height); var dataURL = cvs.toDataURL(type); console.log('dataURL length:',dataURL.length) cvs = null; ctx = null; return dataURL; }; if(!frag&&img.width&&img.height){ //img 加载完才能取出img的数据,如果在domReady 里面执行,图片未加载完会绘制出空白的 canvas console.log('trans directly'); databack.dataURL = trans(img); databack.resolve(); }else{//使用 图片的 natural size,img loaded后才能获得高宽 databack.status = false; var pic = new Image(); pic.crossOrigin = "*"; pic.onload = function(e){ console.log('trans onload'); databack.dataURL = trans(e.target); databack.status = true; databack.resolve(); pic = null; }; pic.src = img.src; } return databack; }, dataURLToBlob:function(dataURL){ console.log(dataURL.length) var type = dataURL.match(/data:(.+?);/); type = type?type[1]:'image/png'; var dataContent = dataURL.replace(/^.+,/,''); dataContent = atob(dataContent); var dataCharCode = []; var i = 0; while(i<dataContent.length){ dataCharCode[i] = dataContent.charCodeAt(i); i++; } var u8Arr = new Uint8Array(dataCharCode); return new Blob([u8Arr],{type:type}); // you maybe use new BolbBuilder() in older browser, maybe canvas.toBlob() is better for image }, readURL:function (input,callback) {//创建预览图 input = input||this.field; if (input.files && input.files[0]) { if(this.maxSize&&input.files[0].size > this.maxSize){ alert('文件大于'+(this.maxSize/(1024*1024))+'m,请重新上传'); return false; } var reader = new FileReader(); reader.onload = function (e) { callback&&callback(e.target.result); }; var dataUrl = reader.readAsDataURL(input.files[0]); reader = null; return dataUrl; } }, upload:function(fileConfig){ var host = this; var formData = new FormData(); var file,name,filename; if(!fileConfig){ name = host.field.name; file = host.field.files[0]; filename = host.field.value.split(/[/\]/).pop()||"temp.png"; }else{ name = fileConfig.name; file = fileConfig.file; filename = fileConfig.filename||"temp.png"; } if(!file){ console.log('no file'); } formData.append(name,file,filename); if(Object(host.extParams)===host.extParams){ $.each(host.extParams,function(k,v){ formData.append(k,v); }); } $.ajax({ url: host.uploadUrl, type: 'POST', data: formData, async: true, dataType:'json', cache: false, contentType: false, processData: false, timeout:45000, success: function (data,status, xhr) { host.afterUpload&&host.afterUpload(data); }, error:function(xhr, errorType, error){ console.log(errorType, error); }, complete:function(xhr, status){ console.log('post complete,status:',status); } }); }//end upload }; return { init:function(config){ return new fileUpLoader(config); } }; })(Zepto); $(document).ready(function(){ upload = uploadImg.init({ field:'uploadimg', viewPane:'viewPane', uploadBtn:'submitbtn', uploadUrl:'yourimguploadurl.jsp', maxSize:0, afterUpload:function(resp){ }, extParams:{uid:12} }); window.onload = function(){ var img = document.querySelector("img"); upload.imgToDataURL(img,'image/jpeg',function(DataURL){ var blob = upload.dataURLToBlob(DataURL); console.log(blob); },true); }; $("#uploadimg").on("change",function(){ var file = this.files[0]; if(!file){ return; } upload.readURL(this,function(dataURL){ upload.viewPane&&(upload.viewPane.src = dataURL); var img = new Image(); img.onload = function(){ var img = document.querySelector("img"); upload.imgToDataURL(img,'image/jpeg',function(dataURL){ var blob = upload.dataURLToBlob(dataURL); console.log(blob); },false); } img.src=dataURL; }); }); }); </script> </head> <body> <div> <img id="viewPane" width="800" height="600" src="img/1111.png" /> <form id="testform"> <!-- camera--照相机;camcorder--摄像机;microphone--录音 --> <input id="uploadimg" type="file" accept="image/*" capture="camera" /> <input id="submitbtn" type="submit" /> </form> </div> </body> </html>
http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
ios 下 canvas 的 drawImage 存在扭曲 bug (似乎是像素过大时出现),修复方法如下
/** 修复 ios 下 canvas drawImage 函数的 画面扭曲BUG * Detecting vertical squash in loaded image. * Fixes a bug which squash image vertically while drawing into canvas for some images. * This is a bug in iOS6 devices. This function from CodeGo.net * */ function detectVerticalSquash(img) { var iw = img.naturalWidth, ih = img.naturalHeight; var canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = ih; var ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); var data = ctx.getImageData(0, 0, 1, ih).data; // search image edge pixel position in case it is squashed vertically. var sy = 0; var ey = ih; var py = ih; while (py > sy) { var alpha = data[(py - 1) * 4 + 3]; if (alpha === 0) { ey = py; } else { sy = py; } py = (ey + sy) >> 1; } var ratio = (py / ih); return (ratio===0)?1:ratio; } /** * A replacement for context.drawImage * (args are for source and destination). * fixed: set height as height/vertSquashRatio */ function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) { var vertSquashRatio = detectVerticalSquash(img); ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio); }
IOS 系统 safari 浏览器上开发 应注意的问题:
https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW15