码迷,mamicode.com
首页 > Web开发 > 详细

Web 本地图片 canvas 截取上传

时间:2016-01-17 11:00:54      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:

我做了一个 Web 本地图片 canvas 截取上传 的demo。发现了几个问题,记录下:

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

 

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

 

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

 

            var clearWidth, clearHeight;
            var imageLoaded = false;
            var cutPoint = {x:0, y:0};
            var gFileName = "";

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

                var originalCanvas = document.getElementById(‘original‘);
                var canvas = document.createElement(‘canvas‘);
                var context = 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 编码
                var data = canvas.toDataURL();
                // 第二个参数的值如果在0.0和1.0之间的话, 会被看作是图片质量参数
                // 但是我测试大小没什么变化
                //var data = canvas.toDataURL(‘image/png‘, 0.5);

                var encodeData = data.split(‘,‘)[1];
                // 解 base64 编码
                var decodedData = window.atob(encodeData);
                var ia = new Uint8Array(decodedData.length);
                for (var i = 0; i < decodedData.length; i++) {
                    ia[i] = decodedData.charCodeAt(i);
                };

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

//                    alert("new Blob exception:" + e);
//                    // TypeError old chrome and FF
//                    var BlobBuilder = window.BlobBuilder ||
//                            window.WebKitBlobBuilder ||
//                            window.MozBlobBuilder ||
//                            window.MSBlobBuilder;
//
//                    alert("BlobBuilder:" + typeof(BlobBuilder));
//                    if(e.name == ‘TypeError‘ && BlobBuilder){
//                        var bb = new BlobBuilder();
//                        bb.append([ia.buffer]);
//                        blob = bb.getBlob("image/png");
//                    } else if(e.name == "InvalidStateError"){
//                        // InvalidStateError (tested on FF13 WinXP)
//                        blob = new Blob( [ia.buffer], {type : "image/png"});
//                    }
//                    else{
//                        // We‘re screwed, blob constructor unsupported entirely
//                        alert("blob constructor unsupported entirely");
//                        return;
//                    }
                }

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

                var fd = new FormData();
                if(blob){
                    fd.append(‘image‘, blob, filename);
                }else{
                    // 采用 base64 上传
                    fd.append("filename", filename);
                    fd.append("image", encodeData);

                    // 由于 base64 大小为原来的 4/3 倍,自然会想能不能像 c 语言那样
                    // 直接把字符当作 unsigned char 来看待。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("post success.");
                    },
                    error: function(){
                        console.log("post failed.");
                    }
                });
            }

 

 

 

Web 本地图片 canvas 截取上传

标签:

原文地址:http://www.cnblogs.com/iexploree/p/5136877.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!