所有分类
  • 所有分类
  • 后端开发
前端图片压缩大揭秘:Canvas神器轻松搞定

前端图片压缩大揭秘:Canvas神器轻松搞定

需要说明的是有两点,这里的resImg是一个预览图片,是已经存在于文档中的,如果你不需要预览,而只是创建一个img用来压缩(document.createElement(img)),这会少一个tagName属性。

<h2>前端图片压缩需求的背景</h2>

我遇到个麻烦事,就是传上去的照片太大,搞得服务器慢吞吞,真让人头疼。为了解决这问题,我得在前端压缩图片并加快上传速度。于是我就开始琢磨各种法子,研究各种技术~

<h2>Canvas压缩原理及应用</h2>

我找到个好法子,直接用Canvas弄个小瘦身。这招儿,就是先把图片丢进美术课的画布上过一遍,再叫Canvas帮咱整成base64字符串存着——最后图像就变瘦了还不失美感!

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 }); 
 };
压缩完成会得到

这部就是在GitHub上找了个好用的小软件搞定的,发现开源社区真给力用Canvas压图这个办法就可以把图片处理到合适大小和清晰度,然后上传超轻松。

<h2>前端图片压缩实践</h2>

试过以后发现,只要input元素有改动,我们就能立刻读到用户发来的照片,甚至可以在页面上实时处理这些照片,对大小进行压缩。这种人机交流方式,用户体验感好,也给服务器减轻很多压力。

 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);
  }
 };

注意了!在用Canvas压缩图片时,不能死板地一个个依次处理,而要根据实际情况灵活调整顺序。只有这么做,才可以保证每张图片都搞定无误~

 fileSelected: function () {
     var files = $("#fileImage")[0].files;
     var count = files.length;
     console.log("共有" + count + "个文件");
     for (var i = 0; i  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);
     }
    },

<h2>不同方式下的前端数据处理</h2>

实战经验,关于如何处理压缩后的图片数据,我试过不少招儿。其中最省事儿的就是先用 base64 编码把原图打的包发给后台,然后就让 MVC 控制器去搞定这事儿。虽说这么做能把本来几兆的大照片压缩成几百KB或几十KB,但千万别忘了调整下宽高和画质系数,免得弄出来的效果难看。

 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);
    },

还有个办法,就是把前端做好的Blob对象交给后台去弄。这样就能随心所欲的操作数据了,而且想怎么处理就怎么处理,看心情哈。

 [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);
   }
  }

咱就直接把这些不需要压缩的图片塞进formdata给下家,超级省事儿!特合适那种没啥特别需求的场合~

<h2>总结与展望</h2>

这篇小知识教你怎么在H5上简化图片上传步骤!做好最重要的两项就可以了,就是选对方法,调整好参数,可以有效节约网络流量,同时保证照片质量棒棒哒!

移动互联网应用把我们扔进了个深坑!需要提升前端性能和用户体验~所以,我们有必要好好学习下图片优化BP技巧。希望看了这篇文章对你有所帮助,下次遇到图片问题就能轻松应对~

 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);

不知道有没有人遇到过同样的问题?快来聊聊你们是怎么搞定前端版权压缩上传的?希望大家能分享下你们的小技巧~

原文链接:https://www.icz.com/technicalinformation/web/2024/04/13342.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?