首頁 >web前端 >js教程 >用HTML5實作圖片壓縮與上傳

用HTML5實作圖片壓縮與上傳

php中世界最好的语言
php中世界最好的语言原創
2018-03-16 10:33:104065瀏覽

這次帶給大家用HTML5實作圖片壓縮與上傳,HTML5實作圖片壓縮與上傳的注意事項有哪些,以下就是實戰案例,一起來看一下。

canvas壓縮

使用了github上的現成函式庫:https://github.com/stomita/ios-imagefile-megapixel,不得不膜拜下stomita這位大神。大體的想法是將圖片抽樣顯示在canvas上,然後用透過canvas.toDataURL方法得到base64字串來實現壓縮。例如在input元素觸發change事件之後,讀取裡面的檔案進行操作:

 fileInput = document.getElementById('fileInput'=  file = fileInput.files[0
     mpImg = 
     resImg = document.getElementById('resultImage'

壓縮完成會得到類似這樣的圖片:

data: image/jpeg 這樣的格式已經套用的很多了,很多樣式裡面的背景圖片直接就是這樣。

需要說明的是有兩點,這裡的resImg是一個預覽圖片,是已經存在於文檔中的,如果你不需要預覽,而只是創建一個img用來壓縮(document.createElement(" img")),這會少一個tagName屬性。你可以修改原始碼或自己加上這個屬性。原始碼中會根據tagName進行判斷,不存在的話會報錯:

 MegaPixImage.prototype.render = function (target, options, callback) {
        //....
        target.tagName = target.tagName || "IMG"; //加上这一句        var tagName = target.tagName.toLowerCase();        if (tagName === 'img') {
            target.src = renderImageToDataURL(this.srcImage, opt, doSquash);
        } else if (tagName === 'canvas') {
            renderImageToCanvas(this.srcImage, target, opt, doSquash);
        }        if (typeof this.onrender === 'function') {            this.onrender(target);
        }        if (callback) {
            callback();
        }        if (this.blob) {            this.blob = null;
            URL.revokeObjectURL(this.srcImage.src);
        }
    };

另外這是一個耗時的操作,如果是多張圖片進行壓縮,不能直接調用,需要稍微變換一下,不然會導致前面的圖片沒有壓縮完成就進入到後面的圖片了。

 fileSelected: function () {                    var files = $("#fileImage")[0].files;                    var count = files.length;
                    console.log("共有" + count + "个文件");                    for (var i = 0; i < count; i++) {var item = files[i];
                        console.log("原图片大小", item.size);                        if (item.size > 1024 * 1024 * 2) {
                            console.log("图片大于2M,开始进行压缩...");
                            (function(img) {                                var mpImg = new MegaPixImage(img);                                var resImg = document.createElement("img");
                                resImg.file = img;
                                mpImg.render(resImg, { maxWidth: 500, maxHeight: 500, quality: 1 }, function() {
                                  //do some thing
                                });
                            })(item);
                        } 
                        core.previewImage(item);
                    }
                },

上傳處理

 1.直接post base64字串

  uploadBase64str: function (base64Str) {
                    var formdata = new FormData();
                    formdata.append("base64str", base64Str);                    var xhr = new XMLHttpRequest();
                    xhr.upload.addEventListener("progress", function (e) {                        var percentComplete = Math.round(e.loaded * 100 / e.total);
                        para.onProgress(percentComplete.toString() + '%');
                    });
                    xhr.addEventListener("load", function (e) {
                        para.uploadComplete(xhr.responseText);
                    });
                    xhr.addEventListener("error", function (e) {
                        para.uploadError(e);
                    });
                    xhr.open("post", para.base64strUrl, true);                    xhr.send(formdata);
                },

例如這裡base64strUrl是/home/MUploadImgBase64Str,MVC控制器方法如下:

 [HttpPost]        public ActionResult MUploadImgBase64Str(string base64str)
        {            try
            {                var imgData = base64str.Split(',')[1];                //过滤特殊字符即可   
                string dummyData = imgData.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+");                if (dummyData.Length % 4 > 0)
                {
                    dummyData = dummyData.PadRight(dummyData.Length + 4 - dummyData.Length % 4, '=');
                }                byte[] byteArray = Convert.FromBase64String(dummyData);                using (System.IO.MemoryStream ms = new System.IO.MemoryStream(byteArray))
                {                    var img = System.Drawing.Image.FromStream(ms);                    var path = "~/Content/UploadFiles/mobile/";                    var uploadpath = Server.MapPath(path);                    if (!Directory.Exists(uploadpath))
                    {
                        Directory.CreateDirectory(uploadpath);
                    }                    var saveName = uploadpath + “stoneniqiu” + ".jpg";
                    img.Save(saveName);                    return Json(saveName);
                }
            }            catch (Exception e)
            {                return Json(e.Message);
            }
        }

幾M的圖片能壓縮到幾十k或幾百k,當然,如果寬度、高度和品質設定的太小,圖片就會很失真了。這個字串怎麼取得呢?有兩個方法,一個是直接讀取src:

 var base641 = resImg.src;

一個是用canvas轉換:

 function getBase64Image(img) {                var canvas = document.createElement("canvas");
                canvas.width = img.width;
                canvas.height = img.height;                var ctx = canvas.getContext("2d");
                ctx.drawImage(img, 0, 0, img.width, img.height);                var dataURL = canvas.toDataURL("image/jpeg");                return dataURL;                // return dataURL.replace("data:image/png;base64,", "");            } var base64 = getBase64Image(resImg);

同一張圖片,這兩者所取得的字串大小不一樣,但圖片品質我是分辨不出什麼差別。

例如一個2M的圖片,透過getBase64Image方法讀到的字串大小才64k,而src直接讀取到的卻是270k,各自產生的圖片更小。一下分別是原圖(2.2M),base64(48k),src(202k)對應的圖片。

   

getBase64Image透過canvas的toDataURL 取得到較小的base64字串。

2.也可以在前端轉換blob對象,再post到後端

 
                 byteString = atob(dataUrl.split(',')[1
 ab =  ia =  ( i = 0; i < byteString.length; i++=  Blob([ab], { type: 'image/jpeg'

3.不壓縮的就直接裝到formdata中,send到後台。

   uploadFile: function (file) {
                    console.log("开始上传");                    var formdata = new FormData();
                    formdata.append(para.filebase, file);//这个名字要和mvc后台配合
                    var xhr = new XMLHttpRequest();
                    xhr.upload.addEventListener("progress", function (e) {                        var percentComplete = Math.round(e.loaded * 100 / e.total);
                        para.onProgress(percentComplete.toString() + '%');
                    });
                    xhr.addEventListener("load", function (e) {
                        para.uploadComplete(xhr.responseText);
                    });
                    xhr.addEventListener("error", function (e) {
                        para.uploadError(e);
                    });
                    xhr.open("post", para.url, true);                        xhr.send(formdata);
                },

我相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

怎麼阻止JS的冒泡與瀏覽器的預設行為

##js與canvas合成圖片做出微信公眾號海報功能

checkbox在jQuery中的使用

DataTable外掛可以實現非同步載入嗎?
#

以上是用HTML5實作圖片壓縮與上傳的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn