Maison >interface Web >Tutoriel H5 >H5 réalise la compression et le téléchargement d'images

H5 réalise la compression et le téléchargement d'images

不言
不言original
2018-06-12 17:27:123928parcourir

Cet article présente principalement en détail la compression d'images H5 et les exemples de téléchargement, qui ont une certaine valeur de référence. Les amis intéressés peuvent s'y référer

Après avoir reçu une demande, demandez si le frontal peut compresser l'image ? Certaines images étant trop volumineuses, il est trop lent de les transférer vers le serveur puis de les compresser. Je n'ai jamais joué comme ça dans ma conscience. Le matin, mon patron m'a envoyé un lien Zhihu, il s'est avéré que les seniors l'avaient déjà implémenté en utilisant Canvas (j'ai eu honte de mes connaissances pendant 3 secondes, puis j'ai commencé à travailler immédiatement) ! .

Compression de toile

En utilisant une bibliothèque prête à l'emploi sur github : https://github.com/stomita/ios-imagefile-megapixel, je dois adorer stomita Ce grand dieu. L'idée générale est d'échantillonner l'image et de l'afficher sur le canevas, puis d'utiliser la méthode canvas.toDataURL pour obtenir la chaîne base64 afin d'obtenir la compression. Par exemple, une fois que l'élément d'entrée a déclenché l'événement de changement, lisez le fichier à l'intérieur et effectuez l'opération :

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

Une image similaire à celle-ci :

data:image/jpeg Ce format a été beaucoup utilisé, et les images d'arrière-plan dans de nombreux styles ressemblent à ceci.

Il y a deux points à noter. Le resImg ici est une image d'aperçu, qui existe déjà dans le document. Si vous n'avez pas besoin d'un aperçu, mais créez simplement une image pour la compression (document.createElement(" img")), qui aura un attribut tagName de moins. Vous pouvez modifier le code source ou ajouter cet attribut vous-même. Le code source sera jugé en fonction du tagName S'il n'existe pas, une erreur sera signalée :

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

De plus, il s'agit d'un opération qui prend du temps, si elle est effectuée sur plusieurs images. La compression ne peut pas être appelée directement. Elle doit être légèrement transformée, sinon l'image précédente entrera dans l'image suivante avant que la compression ne soit terminée.

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

Traitement du téléchargement

1. Publiez directement la chaîne 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() + &#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);
    },

Par exemple, ici base64strUrl est /home/MUploadImgBase64Str, et la méthode du contrôleur MVC est la suivante :

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

   }
  }

Les images M peuvent être compressées à des dizaines ou des centaines de kilo-octets. Bien sûr, si la largeur, la hauteur et la qualité sont trop petites, l'image sera très déformée. Comment obtenir cette chaîne ? Il existe deux méthodes, l'une consiste à lire src directement :

var base641 = resImg.src;

L'autre consiste à utiliser la conversion canevas :

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

Pour une même image, les tailles de cordes obtenues par les deux sont différentes, mais je ne peux pas faire la différence de qualité d'image.

Par exemple, pour une image de 2 Mo, la taille de la chaîne lue via la méthode getBase64Image n'est que de 64 Ko, mais la taille lue directement par src est de 270 Ko, et les images résultantes sont plus petit. Voici les images correspondantes de l'image originale (2,2 Mo), base64 (48 Ko) et src (202 Ko).

getBase64Image obtient une chaîne base64 plus petite via toDataURL du canevas.

2. Vous pouvez également convertir l'objet blob sur le front-end, puis le publier sur le 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. S'il n'est pas compressé, installez-le simplement directement. Accédez à formdata et envoyez-le en arrière-plan.

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

Ce qui précède est l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez prêter attention à. le site PHP chinois !

Recommandations associées :

La fonction de compression et de téléchargement d'images via le développement mobile HTML5

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn