Home  >  Article  >  Web Front-end  >  H5 realizes image compression and uploading

H5 realizes image compression and uploading

不言
不言Original
2018-06-12 17:27:123884browse

This article mainly introduces H5 image compression and uploading examples in detail. It has certain reference value. Interested friends can refer to it.

After receiving the demand, ask the front-end whether it can compress picture? Because some images are too large, it is too slow to transfer them to the server and then compress them. I have never played like this in my consciousness. In the morning, my boss sent me a Zhihu link. When I saw it, it turned out that the seniors had already implemented it using canvas (I was ashamed of my knowledge for 3 seconds, and then started working on it immediately)! .

canvas compression

Using 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 obtain the base64 string to achieve compression. For example, after the input element triggers the change event, read the file inside and perform the operation:

var fileInput = document.getElementById('fileInput');
 fileInput.onchange = function() {
 var file = fileInput.files[0];
 // 创建一个压缩对象,该构造函数接收file或者blob。
 var mpImg = new MegaPixImage(file);

 // render方法的maxWith,maxHeight,以及quality都决定了压缩图片的质量
 var resImg = document.getElementById('resultImage');
 mpImg.render(resImg, { maxWidth: 300, maxHeight: 300, quality: 0.5 }); 
 };
压缩完成会得到

A picture similar to this:

data:image/jpeg This format 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 be judged based on the 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, and needs to be slightly transformed, otherwise the previous image will enter the later image 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. Post base64 string directly

 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() + &#39;%&#39;);
     });
     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, base64strUrl here is /home/MUploadImgBase64Str. The MVC controller method is as follows:

 [HttpPost]
  public ActionResult MUploadImgBase64Str(string base64str)
  {
   try
   {
    var imgData = base64str.Split(&#39;,&#39;)[1];
    //过滤特殊字符即可 
    string dummyData = imgData.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+");
    if (dummyData.Length % 4 > 0)
    {
     dummyData = dummyData.PadRight(dummyData.Length + 4 - dummyData.Length % 4, &#39;=&#39;);
    }
    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);

   }
  }

How many MB of pictures can be compressed? Tens of k or hundreds of k. 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;

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 I can't tell the difference in picture 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 canvas's toDataURL.

2. You can also convert the blob object on the front end and then post it to the back end

 function dataURItoBlob(dataUrl) {
    
    var byteString = atob(dataUrl.split(&#39;,&#39;)[1]);

    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
     ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: &#39;image/jpeg&#39; });
   }

3. If it is not compressed, install it directly into formdata in, send to the background.

 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() + &#39;%&#39;);
     });
     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);
    },

The above is the entire content of this article. I hope it will be helpful to everyone’s study. For more related content, please pay attention to the PHP Chinese website!

Related recommendations:

Implement image compression upload function through HTML5 mobile development

##

The above is the detailed content of H5 realizes image compression and uploading. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn