Home >Web Front-end >JS Tutorial >Implementation of Vue.js 2.0 mobile-side camera compressed image upload preview function

Implementation of Vue.js 2.0 mobile-side camera compressed image upload preview function

不言
不言Original
2018-06-29 15:58:465514browse

This article mainly introduces the Vue.js 2.0 mobile camera compressed image upload preview function. It is very good and has reference value. Friends in need can refer to it

when learning and using Vue.js 2.0 We encountered many differences during the process. We originally developed H5 applications on the mobile terminal and planned to combine the mui framework with the Vue.js vue-router vuex family bucket. However, during the implementation process of taking photos and uploading, we encountered the problem that plus could not be called. There was a problem with the H5 interface, so in the end the photo upload function was solved using the input file method. But I still feel unwilling to do so. Due to the progress of the project and the iteration of versions, I have to give up. In the future, I may use the H5 interface to implement this function.

First of all, let me talk about my idea of ​​​​implementing this photo preview, compression and upload. To be precise, it should be the process of previewing and uploading after taking a photo or selecting image compression. Take a photo or select an image each time - then compress the image - preview and upload. The uploaded image compression plug-in is localResizeIMG. The instructions for using this plug-in can be found on the wiki. The basic principle is to render the image through canvas, and then compress and save it into a base64 string through the toDataURL method (which can be compiled into a jpg format image). The compression effect is very good. If you take a 2MB photo on iOS and compress it, it will be about 60-80kb. The distortion is not too serious, but for my project, the picture is clearly visible. There will also be a demonstration of its use in the code I posted.

<template>
 <h5 class="content-header">图片列表</h5>
 <p class="image-list">
 <p class="list-default-img" v-show="isPhoto" @click.stop="addPic">
 <img src="./images/icon_photo.png" />
 <span>请选择或者拍照上传照片</span>
 <input type="file" accept="image/jpeg,image/jpg,image/png" capture="camera" @change="onFileChange" style="display: none;">
 </p>
 <ul class="list-ul" v-show="!isPhoto">
 <li class="list-li" v-for="(iu, index) in imgUrls">
 <a class="list-link" @click=&#39;previewImage(iu)&#39;>
  <img :src="iu">
 </a>
 <span class="list-img-close" @click=&#39;delImage(index)&#39;></span>
 </li>
 <li class="list-li-add">
 <span class="add-img" @click.stop="addPic"></span>
 </li>
 </ul>
 </p>
 <p class="add-preview" v-show="isPreview" @click="closePreview">
 <img :src="previewImg">
 </p>
 
</template>
<script>
 export default {
 data: function () {
 return {
 imgUrls: [],
 urlArr: [],
 isPhoto: true,
 btnTitle: &#39;&#39;,
 isModify: false,
 previewImg:&#39;&#39;,
 isPreview: false
 }
 },
 watch: {
 imgUrls: &#39;toggleAddPic&#39;
 },
 methods: {
 toggleAddPic: function() {
 let vm = this;
 if(vm.imgUrls.length >= 1) {
  vm.isPhoto = false;
 } else {
  vm.isPhoto = true;
 }
 },
 addPic: function(e) {
 let vm = this;
 $(&#39;input[type=file]&#39;).trigger(&#39;click&#39;);
 return false;
 },
 onFileChange: function(e) {
 var files = e.target.files || e.dataTransfer.files;
 if(!files.length) return;
 this.createImage(files, e);
 },
 createImage: function(file, e) {
 let vm = this;
 lrz(file[0], { width: 480 }).then(function(rst) {
  vm.imgUrls.push(rst.base64);
  return rst;
 }).always(function() {
 // 清空文件上传控件的值
 e.target.value = null;
 });
 },
 delImage: function(index) {
 let vm = this;
 let btnArray = [&#39;取消&#39;, &#39;确定&#39;];
 mui.confirm(&#39;确定删除该图片?&#39;,&#39;提示&#39;, btnArray, function(e) {
  if (e.index == 1) {
  vm.imgUrls.splice(index, 1);
  }
 })
 },
 previewImage: function(url){
 let vm = this;
 vm.isPreview = true;
 vm.previewImg = url;
 },
 closePreview: function(){
 let vm = this;
 vm.isPreview = false;
 vm.previewImg = "";
 },
 saveImage: function(){
 let vm = this;
 let urlArr = [],
 imgUrls = this.imgUrls;
 for(let i = 0; i < imgUrls.length; i++) {
  if(imgUrls[i].indexOf(&#39;file&#39;) == -1) {
  urlArr.push(imgUrls[i].split(&#39;,&#39;)[1]);
  } else {
  urlArr.push(imgUrls[i]);
  }
 }
 //数据传输操作
 }
 }
 }
 
</script>

1. Click to take a photo or select a pictureaddPic

Taking pictures and selecting pictures in vue.js are frequent operations. You can only take a picture or select one at a time. You can take multiple pictures and upload them. Use the .stop modifier on the click event. .stop - call event.stopPropagation() to stop bubbling. Accept is to specify the type of file submitted through file upload. Capture is the default device captured by the system in the webApp. camera--camera; camcorder--camera; microphone--recording.

Bind the change event onFileChange to obtain the file object when the photo taking action is triggered, then call the lrz method to compress the image, and add the image based on base64 format to the imgUrls array.

lrz(file[0], { width: 480 }).then(function(rst) {
  vm.imgUrls.push(rst.base64);
  return rst;
 }).always(function() {
 // 清空文件上传控件的值
 e.target.value = null;
 });
lrz(file, [options]);

file: The file obtained through input:file, or directly pass in the image path.

[options]: This parameter can be ignored.

width {Number} The maximum width of the image, which defaults to the width of the original image. If the height is not set, it will adapt to the width;
height {Number} Same as above;
quality {Number} image compression quality , value 0 - 1, default is 0.7;
fieldName {String} field name received by the backend, default: file;

The return result is a promise object, including then(), catch() , always three methods.

then(rst):

rst.formData data that can be processed by the backend;
rst.file compressed file object (already lost in rst by default .formData has a copy). It should be noted that if the compression rate is too low, this will be the original file object;
rst.fileLen is the size of the generated image. The backend can use this value to verify whether to transmit it. Complete;
rst.base64 The generated image base64, the backend can process this string into an image, and it can also be used directly for img.src = base64;
rst.base64Len The size of the generated base64, the backend can Use this value to verify whether the transmission is complete (if the base64 upload method is used);
rst.origin is the original file object, which stores some original file information, such as size, date, etc.;

catch(err), always().

Note: Since we may continue to click to take photos and upload pictures, the value of the upload control must be cleared in the always callback function.

// 清空文件上传控件的值
 e.target.value = null;

2. Click to take the first photo and display the preview and the DOM display for continuing to take pictures isPhoto

The default isPhoto is true, hide the DOM display for continuing to take pictures, toggleAddPic Monitor the length of the currently selected imgUrls array and convert the Boolean value of isPhoto. If there is one or more pictures and set isPhoto to false, the DOM that clicks to take the first picture will be hidden, and the DOM that continues to take pictures will be displayed; if there is no picture, the DOM that continues to take pictures will be hidden. , showing the DOM of the first photo taken.

3. Delete the selected compressed image delImage

According to the subscript corresponding to the array, delete the corresponding image data in imgUrls.

delImage: function(index) {
 let vm = this;
 let btnArray = [&#39;取消&#39;, &#39;确定&#39;];
 mui.confirm(&#39;确定删除该图片?&#39;,&#39;提示&#39;, btnArray, function(e) {
  if (e.index == 1) {
  vm.imgUrls.splice(index, 1);
  }
 })
 }

4. Preview the compressed image and close the large image preview isPreview previewImage closePreview

    在这里大图预览就是将base64格式的图片直接放进预览DOM的img src中放大展示,点击图片自身关闭预览,清空img src资源。

5. 对base64图片传输前的处理 saveImage

saveImage: function(){
 let vm = this;
 let urlArr = [],
 imgUrls = this.imgUrls;
 for(let i = 0; i < imgUrls.length; i++) {
  if(imgUrls[i].indexOf(&#39;file&#39;) == -1) {
  urlArr.push(imgUrls[i].split(&#39;,&#39;)[1]);
  } else {
  urlArr.push(imgUrls[i]);
  }
 }
 //数据传输操作
 }

我压缩成base64字符串是“data:image/jpeg;base64,~~”的字符串,为了后端好处理,我这里为了将编辑时候后台返回的图片url区别开来,将“data:image/jpeg;base64,"截取掉,只传递给后端逗号后面的base64字符串。

注意:后端接收到我传递的base64字符串数组的时候,发现字符经如果被urlencode后标准的base64中的/、 +会被转成%xx,后端在将base64字符串处理成图片时,需要将特殊字符过滤掉。

  public ActionResult MUploadImgBase64Str(string base64str)
  {
   try
   {
    var imgData = base64str;
    //过滤特殊字符即可 
    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);
   }
  }

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

相关推荐:

基于casperjs和resemble.js实现一个像素对比服务

vue 实现剪裁图片并上传服务器的功能介绍

The above is the detailed content of Implementation of Vue.js 2.0 mobile-side camera compressed image upload preview function. 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