Home Web Front-end H5 Tutorial The mobile terminal uses H5 to implement the function of compressing image uploads

The mobile terminal uses H5 to implement the function of compressing image uploads

Jun 11, 2018 pm 04:41 PM

This article mainly introduces in detail the use of H5 on the mobile terminal to realize the compressed image upload function. It has a certain reference value. Interested friends can refer to it.

A colleague talked to me before Regarding the function of using canvas to compress images on the mobile terminal and then upload them, I recently had some free time, so I put it into practice. The demo effect link is posted at the bottom of the article.

When uploading pictures on the mobile terminal, users upload local pictures on the mobile phone, and local pictures are generally relatively large. Take iPhone6 ​​as an example. Many pictures usually taken are one or two megabytes in size. If If you upload it directly like this, the image will be too big. If the user uses mobile data, uploading the image completely is obviously not a good idea.

Currently, various new APIs of HTML5 have been better implemented on mobile webkit. According to caniuse, the FileReader, Blob, and Formdata objects used in this demo have been implemented in most mobile device browsers (safari6.0, android 3.0), so compressing images directly on the front end has become a common problem for many mobile devices. It is a necessary function for uploading pictures on the terminal.

Compressing and uploading images on the mobile terminal mainly uses the three h5 APIs of filereader, canvas and formdata. The logic is not difficult. The whole process is:

 (1) When the user uses input file to upload pictures, use filereader to read the picture data uploaded by the user (base64 format)

 (2) Pass the picture data into img Object, then draw img to canvas, and then call canvas.toDataURL to compress the image

(3) Obtain the compressed base64 format image data, convert it into binary and insert it into formdata, and then submit the formdata through XmlHttpRequest .

In these three steps, the image compression and uploading are completed.

It sounds simple, but in fact there are still some pitfalls. Next, use the code to analyze it directly:

[1] Obtain image data

First, obtain the image data, that is, listen to the change event of the input file, and then obtain For the uploaded file object files, convert the array-like files into an array, and then perform forEach traversal.

Next, determine the file type. If it is not a picture, it will not be processed. If it is a picture, instantiate a filereader, read the uploaded file data in base64 format, and determine the data length. If the picture is larger than 200KB, call the compress method to compress it, otherwise call the upload method to upload.

filechooser.onchange = function () {
   if (!this.files.length) return;
 
   var files = Array.prototype.slice.call(this.files);
 
   if (files.length > 9) {
    alert("最多同时只可上传9张图片");
    return;
   }
 
   files.forEach(function (file, i) {
    if (!/\/(?:jpegpnggif)/i.test(file.type)) return;
 
    var reader = new FileReader();
 
    var li = document.createElement("li");
    li.innerHTML = "<p class="progress"><span></span></p>";
    $(".img-list").append($(li));
 
    reader.onload = function () {
     var result = this.result;
     var img = new Image();
     img.src = result;
 
     //如果图片大小小于200kb,则直接上传
     if (result.length <= maxsize) {
      $(li).css("background-image", "url(" + result + ")");
      img = null;
      upload(result, file.type, $(li));
 
      return;
     }
 
 //    图片加载完毕之后进行压缩,然后上传
     if (img.complete) {
      callback();
     } else {
      img.onload = callback;
     }
 
     function callback() {
      var data = compress(img);
 
      $(li).css("background-image", "url(" + data + ")");
 
      upload(data, file.type, $(li));
 
      img = null;
     }
 
    };
 
    reader.readAsDataURL(file);
   })
  };
Copy after login

【2】Compress images

After completing the acquisition of image data above, you can perform compress compression Picture method. Compressing images does not involve directly drawing the image to canvas and then calling toDataURL.

In IOS, there are two limitations for drawing pictures on canvas:

The first is the size of the picture. If the size of the picture exceeds two million pixels, the picture cannot be drawn on the canvas. , no error will be reported when calling drawImage, but when you use toDataURL to obtain image data, you will get empty image data.

Furthermore, the size of the canvas is limited. If the size of the canvas is larger than about five million pixels (i.e., the product of width and height), not only the picture cannot be drawn, but also other things cannot be drawn. .

To deal with the first limitation, the solution is to draw tiles. Tile drawing is to divide the picture into multiple pieces and draw them on the canvas. The method in my code is to divide the picture into 1 million pixels and then draw it on the canvas.

To deal with the second limitation, my solution is to appropriately compress the width and height of the image. For the sake of safety, the upper limit set in my code is four million pixels. If the image is larger than four million pixels, Just compress it to less than 4 million pixels. A 4-megapixel image should be enough, with a width and height of 2000X2000.

In this way, the two limitations on IOS are solved.

In addition to the limitations mentioned above, there are two pitfalls. One is that the toDataURL of canvas can only compress jpg. When the image uploaded by the user is png, it needs to be converted to jpg, that is, it can be used uniformly. canvas.toDataURL("image/jpeg", 0.1), the type is uniformly set to jpeg, and the compression ratio is controlled by itself.

The other is that if you convert png to jpg and draw it on the canvas, if there is a transparent area in the canvas, the transparent area will turn black when you convert it to jpg, because the transparent pixels of the canvas default to rgba( 0,0,0,0), so when converted to jpg, it becomes rgba(0,0,0,1), that is, the transparent background will become black. The solution is to lay a white background on the canvas before drawing.

function compress(img) {
  var initSize = img.src.length;
  var width = img.width;
  var height = img.height;

  //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
  var ratio;
  if ((ratio = width * height / 4000000)>1) {
   ratio = Math.sqrt(ratio);
   width /= ratio;
   height /= ratio;
  }else {
   ratio = 1;
  }

  canvas.width = width;
  canvas.height = height;

//  铺底色
  ctx.fillStyle = "#fff";
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  //如果图片像素大于100万则使用瓦片绘制
  var count;
  if ((count = width * height / 1000000) > 1) {
   count = ~~(Math.sqrt(count)+1); //计算要分成多少块瓦片

//   计算每块瓦片的宽和高
   var nw = ~~(width / count);
   var nh = ~~(height / count);

   tCanvas.width = nw;
   tCanvas.height = nh;

   for (var i = 0; i < count; i++) {
    for (var j = 0; j < count; j++) {
     tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);

     ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
    }
   }
  } else {
   ctx.drawImage(img, 0, 0, width, height);
  }

  //进行最小压缩
  var ndata = canvas.toDataURL("image/jpeg", 0.1);

  console.log("压缩前:" + initSize);
  console.log("压缩后:" + ndata.length);
  console.log("压缩率:" + ~~(100 * (initSize - ndata.length) / initSize) + "%");

  tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;

  return ndata;
 }
Copy after login

[3] Image upload

After the image compression is completed, it can be inserted into formdata and uploaded. , first convert the base64 data into a string, then instantiate an ArrayBuffer, then pass the string into the ArrayBuffer in the format of an 8-bit integer, and then use the BlobBuilder or Blob object to convert the 8-bit integer ArrayBuffer into a binary object blob , then append the blob object to formdata, and then send it to the background through ajax.

XmlHttpRequest2 not only can send big data, but also has additional APIs such as obtaining the sending progress, which I have also implemented in a simple way in my code.

// 图片上传,将base64的图片转成二进制对象,塞进formdata上传
 function upload(basestr, type, $li) {
  var text = window.atob(basestr.split(",")[1]);
  var buffer = new ArrayBuffer(text.length);
  var ubuffer = new Uint8Array(buffer);
  var pecent = 0 , loop = null;

  for (var i = 0; i < text.length; i++) {
   ubuffer[i] = text.charCodeAt(i);
  }

  var Builder = window.WebKitBlobBuilder window.MozBlobBuilder;
  var blob;

  if (Builder) {
   var builder = new Builder();
   builder.append(buffer);
   blob = builder.getBlob(type);
  } else {
   blob = new window.Blob([buffer], {type: type});
  }

  var xhr = new XMLHttpRequest();
  var formdata = new FormData();
  formdata.append("imagefile", blob);

  xhr.open("post", "/cupload");

  xhr.onreadystatechange = function () {
   if (xhr.readyState == 4 && xhr.status == 200) {
    console.log("上传成功:" + xhr.responseText);

    clearInterval(loop);

    //当收到该消息时上传完毕
    $li.find(".progress span").animate({"width": "100%"}, pecent < 95 ? 200 : 0, function () {
     $(this).html("上传成功");
    });

    $(".pic-list").append("<a href="" + xhr.responseText + " rel="external nofollow" ">" + xhr.responseText + "<img src="" + xhr.responseText + "" /></a>")
   }
  };

  //数据发送进度,前50%展示该进度
  xhr.upload.addEventListener("progress", function (e) {
   if (loop) return;

   pecent = ~~(100 * e.loaded / e.total) / 2;
   $li.find(".progress span").css("width", pecent + "%");

   if (pecent == 50) {
    mockProgress();
   }
  }, false);

  //数据后50%用模拟进度
  function mockProgress() {
   if (loop) return;

   loop = setInterval(function () {
    pecent++;
    $li.find(".progress span").css("width", pecent + "%");

    if (pecent == 99) {
     clearInterval(loop);
    }
   }, 100)
  }

  xhr.send(formdata);
 }
Copy after login

     至此,整个上传的前端图片压缩就完成了,因为是用了formdata提交,所以后台接数据的时候就跟普通form表单提交数据一样处理即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

关于H5调用相机拍照并压缩图片的代码

关于H5新属性audio音频和video视频的控制解析

Angular下H5多张上传图片的方法

The above is the detailed content of The mobile terminal uses H5 to implement the function of compressing image uploads. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
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

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to run the h5 project How to run the h5 project Apr 06, 2025 pm 12:21 PM

Running the H5 project requires the following steps: installing necessary tools such as web server, Node.js, development tools, etc. Build a development environment, create project folders, initialize projects, and write code. Start the development server and run the command using the command line. Preview the project in your browser and enter the development server URL. Publish projects, optimize code, deploy projects, and set up web server configuration.

What exactly does H5 page production mean? What exactly does H5 page production mean? Apr 06, 2025 am 07:18 AM

H5 page production refers to the creation of cross-platform compatible web pages using technologies such as HTML5, CSS3 and JavaScript. Its core lies in the browser's parsing code, rendering structure, style and interactive functions. Common technologies include animation effects, responsive design, and data interaction. To avoid errors, developers should be debugged; performance optimization and best practices include image format optimization, request reduction and code specifications, etc. to improve loading speed and code quality.

How to make h5 click icon How to make h5 click icon Apr 06, 2025 pm 12:15 PM

The steps to create an H5 click icon include: preparing a square source image in the image editing software. Add interactivity in the H5 editor and set the click event. Create a hotspot that covers the entire icon. Set the action of click events, such as jumping to the page or triggering animation. Export H5 documents as HTML, CSS, and JavaScript files. Deploy the exported files to a website or other platform.

What is the H5 programming language? What is the H5 programming language? Apr 03, 2025 am 12:16 AM

H5 is not a standalone programming language, but a collection of HTML5, CSS3 and JavaScript for building modern web applications. 1. HTML5 defines the web page structure and content, and provides new tags and APIs. 2. CSS3 controls style and layout, and introduces new features such as animation. 3. JavaScript implements dynamic interaction and enhances functions through DOM operations and asynchronous requests.

Is H5 page production a front-end development? Is H5 page production a front-end development? Apr 05, 2025 pm 11:42 PM

Yes, H5 page production is an important implementation method for front-end development, involving core technologies such as HTML, CSS and JavaScript. Developers build dynamic and powerful H5 pages by cleverly combining these technologies, such as using the &lt;canvas&gt; tag to draw graphics or using JavaScript to control interaction behavior.

How to make pop-up windows with h5 How to make pop-up windows with h5 Apr 06, 2025 pm 12:12 PM

H5 pop-up window creation steps: 1. Determine the triggering method (click, time, exit, scroll); 2. Design content (title, text, action button); 3. Set style (size, color, font, background); 4. Implement code (HTML, CSS, JavaScript); 5. Test and deployment.

What application scenarios are suitable for H5 page production What application scenarios are suitable for H5 page production Apr 05, 2025 pm 11:36 PM

H5 (HTML5) is suitable for lightweight applications, such as marketing campaign pages, product display pages and corporate promotion micro-websites. Its advantages lie in cross-platformity and rich interactivity, but its limitations lie in complex interactions and animations, local resource access and offline capabilities.

What Does H5 Refer To? Exploring the Context What Does H5 Refer To? Exploring the Context Apr 12, 2025 am 12:03 AM

H5referstoHTML5,apivotaltechnologyinwebdevelopment.1)HTML5introducesnewelementsandAPIsforrich,dynamicwebapplications.2)Itsupportsmultimediawithoutplugins,enhancinguserexperienceacrossdevices.3)SemanticelementsimprovecontentstructureandSEO.4)H5'srespo

See all articles