Web 本地圖片 canvas 截取上傳

jopen 8年前發布 | 8K 次閱讀 前端技術 JavaScript

我做了一個 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.  a ndroid 老的原生 手機瀏覽器  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.");
                }
            });
        }</pre> </div>

來自: http://www.cnblogs.com/iexploree/p/5136877.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!