Home > Article > Web Front-end > Image compression and uploading using HTML5
This time I will bring you the use of HTML5 to compress and upload images. What are the precautions for implementing image compression and upload in HTML5? The following is a practical case, let's take a look.
canvas compressionUsing a ready-made library on github:https://github.com/stomita/ios-imagefile-megapixel, I have to worship stomita This great god. The general idea is to sample the image and display it on the canvas, and then use the canvas.toDataURL method to get the base64string to achieve compression. For example, after the input element triggers the change event, read the file inside and perform the operation:
fileInput = document.getElementById('fileInput'= file = fileInput.files[0 mpImg = resImg = document.getElementById('resultImage'After the compression is completed, you will get a picture similar to this: data: Format like image/jpeg has been used a lot, and the background images in many styles are just like this. There are two points to note. The resImg here is a preview image, which already exists in the document. If you do not need a preview, but just create an img for compression (document.createElement(" img")), which will have one less tagName attribute. You can modify the source code or add this attribute yourself. The source code will judge based on tagName. If it does not exist, an error will be reported:
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); } };In addition, this is a time-consuming operation. If multiple pictures are compressed, it cannot be called directly. It needs to be slightly transformed, otherwise it will cause The previous picture enters the later picture without being compressed.
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); } },Upload processing 1. Directly post base64 string
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); },For example, here base64strUrl is /home/MUploadImgBase64Str, MVC
ControllerThe method is as follows:
[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); } }Pictures of several MB can be compressed to tens of kilobytes or hundreds of kilobytes. Of course, if the width, height and quality are set too small, the picture will be very distorted. How to get this string? There are two methods, one is to read src directly:
var base641 = resImg.src;and the other is to use canvas conversion:
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);For the same picture, the string sizes obtained by the two are different, but the picture I can't tell any difference in quality. For example, for a 2M picture, the string size read through the getBase64Image method is only 64k, but the size read directly by src is 270k, and the resulting pictures are smaller. . The following are the corresponding images of the original image (2.2M), base64 (48k), and src (202k).
getBase64Image obtains a smaller base64 string through the toDataURL of canvas. 2. You can also convert the blob object on the front end and then post it to the backend
byteString = atob(dataUrl.split(',')[1 ab = ia = ( i = 0; i < byteString.length; i++= Blob([ab], { type: 'image/jpeg'3. If it is not compressed, install it directly into formdata and send it to the backend.
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); },I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the php Chinese website! Recommended reading:
How to prevent JS bubbling and the browser’s default behavior
js and canvas composite images Create a WeChat public account poster function
Can the DataTable plug-in realize asynchronous loading? ?
The above is the detailed content of Image compression and uploading using HTML5. For more information, please follow other related articles on the PHP Chinese website!