您的位置:首页 > 其它

Web 本地图片 canvas 截取上传

2016-01-17 10:40 211 查看
我做了一个Web本地图片canvas截取上传的demo。发现了几个问题,记录下:

1.Canvas元素大小(csswidthheight)和表面大小(canvas自身的widthheight属性)两个概念是不一样的,当两个大小不一致时,坐标需要进行转换计算。

//其中x,y是视口坐标
functionwindowToCanvas(canvas,x,y){
varbbox=canvas.getBoundingClientRect();
return{x:(x-bbox.left)*(canvas.width/bbox.width),
y:(y-bbox.top)*(canvas.height/bbox.height)
};
}


2.android老的原生手机浏览器Blob构造函数有bug(比如使用微信或qq浏览器,newBlob()会抛出异常),我的解决方法是使用base64上传,服务端解码。由于base64大小为原来的4/3倍,自然会想能不能像c语言那样接把字符当作unsignedchar来看待。仔细一想js是不行的。因text+=1,数字1将被转换为字符串"1",而text[i]是仅可读,不修改!

varclearWidth,clearHeight;
varimageLoaded=false;
varcutPoint={x:0,y:0};
vargFileName="";

document.getElementById('uploadbtn').onclick=function(){
if(!imageLoaded){
return;
}

varoriginalCanvas=document.getElementById('original');
varcanvas=document.createElement('canvas');
varcontext=canvas.getContext('2d');
canvas.width=clearWidth;
canvas.height=clearHeight;
context.drawImage(originalCanvas,cutPoint.x,cutPoint.y,clearWidth,clearHeight,0,0,clearWidth,clearHeight);

//注意toDataURL返回的默认是png格式
//data是base64编码
vardata=canvas.toDataURL();
//第二个参数的值如果在0.0和1.0之间的话,会被看作是图片质量参数
//但是我测试大小没什么变化
//vardata=canvas.toDataURL('image/png',0.5);

varencodeData=data.split(',')[1];
//解base64编码
vardecodedData=window.atob(encodeData);
varia=newUint8Array(decodedData.length);
for(vari=0;i<decodedData.length;i++){
ia[i]=decodedData.charCodeAt(i);
};

varblob;
try{
//toDataURL返回的默认是png格式,所以这里固定为image/png
blob=newBlob([ia],{type:"image/png"});
}catch(e){
//使用http://haomou.net/2016/01/14/2016_android_blob/仍然无法解决
//android手机浏览器Blob构造函数bug
//我的解决方法是使用base64上传,服务端解码

//alert("newBlobexception:"+e);
////TypeErroroldchromeandFF
//varBlobBuilder=window.BlobBuilder||
//window.WebKitBlobBuilder||
//window.MozBlobBuilder||
//window.MSBlobBuilder;
//
//alert("BlobBuilder:"+typeof(BlobBuilder));
//if(e.name=='TypeError'&&BlobBuilder){
//varbb=newBlobBuilder();
//bb.append([ia.buffer]);
//blob=bb.getBlob("image/png");
//}elseif(e.name=="InvalidStateError"){
////InvalidStateError(testedonFF13WinXP)
//blob=newBlob([ia.buffer],{type:"image/png"});
//}
//else{
////We'rescrewed,blobconstructorunsupportedentirely
//alert("blobconstructorunsupportedentirely");
//return;
//}
}

//修改文件名后缀格式
varfilename=gFileName;
varindex=filename.lastIndexOf('.');
if(index>=0){
filename=filename.substring(0,index);
filename+=".png";
}

varfd=newFormData();
if(blob){
fd.append('image',blob,filename);
}else{
//采用base64上传
fd.append("filename",filename);
fd.append("image",encodeData);

//由于base64大小为原来的4/3倍,自然会想能不能像c语言那样
//直接把字符当作unsignedchar来看待。js是不行的。因为
//text+=1,数字1将被转换为字符串"1",而text[i]是仅可读,不
//可修改!
}

//使用ajax发送
$.ajax({
url:"http://192.168.3.102:8080/upload",
type:"POST",
data:fd,
processData:false,//告诉jQuery不要去处理发送的数据
contentType:false,//告诉jQuery不要去设置Content-Type请求头
success:function(){
console.log("postsuccess.");
},
error:function(){
console.log("postfailed.");
}
});
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: