Browse Source

feat: 图片压缩

From-wh 2 năm trước cách đây
mục cha
commit
f5f09df348

+ 22 - 25
template/admin/src/components/uploadImg/index.vue

@@ -128,6 +128,7 @@ import Setting from '@/setting';
 import { getCookies } from '@/libs/util';
 import { fileUpload, scanUploadQrcode, scanUploadGet } from '@/api/setting';
 import QRCode from 'qrcodejs2';
+import compressImg from '@/utils/compressImg.js';
 
 export default {
   name: '',
@@ -231,33 +232,25 @@ export default {
         const formData = new FormData();
         formData.append('file', file);
         formData.append('pid', this.treeId);
-        fileUpload(formData).then((res) => {
-          if (res.status == 200) {
-            resolve();
-            // this.$emit('uploadImgSuccess', res.data);
-          } else {
-            this.$message({
-              message: '上传失败',
-              type: 'error',
-              duration: 1000,
-            });
-          }
-        });
+        fileUpload(formData)
+          .then((res) => {
+            if (res.status == 200) {
+              resolve();
+              // this.$emit('uploadImgSuccess', res.data);
+            } else {
+              this.$message({
+                message: '上传失败',
+                type: 'error',
+                duration: 1000,
+              });
+            }
+          })
+          .catch((err) => {
+            this.$Message.error(err.msg);
+          });
       });
     },
-    beforeUpload(file) {
-      //   console.log('1s ');
-      //   if (!/image\/\w+/.test(file.type)) {
-      //     this.$Message.error('请上传以jpg、jpeg、png等结尾的图片文件'); //FileExt.toLowerCase()
-      //     return false;
-      //   }
-      //   let promise = new Promise((resolve) => {
-      //     this.$nextTick(function () {
-      //       resolve(true);
-      //     });
-      //   });
-      //   return promise;
-    },
+    beforeUpload(file) {},
     creatQrCode(url) {
       this.$refs.qrCodeUrl.innerHTML = '';
       var qrcode = new QRCode(this.$refs.qrCodeUrl, {
@@ -286,6 +279,10 @@ export default {
     fileChange(file, fileList) {
       console.log(file, fileList);
       this.ruleForm.imgList = fileList;
+      compressImg(file.raw).then((res) => {
+        if (fileList.length) fileList[fileList.length - 1].raw = res;
+        this.ruleForm.imgList = fileList;
+      });
     },
     loadData(item, callback) {
       getCategoryListApi({

+ 23 - 6
template/admin/src/pages/app/upload/index.vue

@@ -39,6 +39,7 @@
 <script>
 import Setting from '@/setting';
 import { scanUpload } from '@/api/setting';
+import compressImg from '@/utils/compressImg.js';
 export default {
   name: 'app_upload_file',
   data() {
@@ -52,8 +53,8 @@ export default {
   },
   created() {
     this.token = this.$route.query.token;
+    document.title = '手机端扫码上传';
   },
-  mounted() {},
   methods: {
     again() {
       this.uploading = true;
@@ -77,10 +78,11 @@ export default {
       this.imgList.splice(index, 1);
       this.$nextTick((e) => {
         this.imgList.map((e) => {
-          this.allSize += e.size;
+          this.allSize += e.raw.size;
         });
       });
     },
+
     uploadItem(file) {
       return new Promise((resolve, reject) => {
         const formData = new FormData();
@@ -103,11 +105,26 @@ export default {
           });
       });
     },
+
+    dataURLtoBlob(dataurl) {
+      const arr = dataurl.split(','),
+        mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]);
+      let n = bstr.length;
+      const u8arr = new Uint8Array(n);
+      while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+      }
+      return new Blob([u8arr], { type: mime });
+    },
     fileChange(file, fileList) {
-      this.imgList = fileList;
-      console.log(this.imgList);
-      this.imgList.map((e) => {
-        this.allSize += e.size;
+      compressImg(file.raw).then((res) => {
+        if (fileList.length) fileList[fileList.length - 1].raw = res;
+        this.imgList = fileList;
+        this.imgList.map((e) => {
+          console.log(e);
+          this.allSize += e.raw.size;
+        });
       });
     },
     loadData(item, callback) {

+ 65 - 0
template/admin/src/utils/compressImg.js

@@ -0,0 +1,65 @@
+/**
+ * @压缩公共方法
+ * @params file
+ * @return 压缩后的文件,支持两种,file和 blob
+ */
+export default function compressImg(file) {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    // readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,
+    // 同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
+    reader.readAsDataURL(file);
+    reader.onload = () => {
+      const img = new Image();
+      img.src = reader.result;
+      img.onload = () => {
+        // 图片的宽高
+        const w = img.width;
+        const h = img.height;
+        const canvas = document.createElement('canvas');
+        // canvas对图片进行裁剪,这里设置为图片的原始尺寸
+        canvas.width = w;
+        canvas.height = h;
+        const ctx = canvas.getContext('2d');
+        // canvas中,png转jpg会变黑底,所以先给canvas铺一张白底
+        ctx.fillStyle = '#fff';
+        // fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在
+        // (x, y) ,它的宽度和高度分别由width 和 height 确定,填充样式由当前的fillStyle 决定。
+        ctx.fillRect(0, 0, canvas.width, canvas.height);
+        // 绘制图像
+        ctx.drawImage(img, 0, 0, w, h);
+
+        // canvas转图片达到图片压缩效果
+        // 返回一个包含图片展示的 data URI base64 在指定图片格式为 image/jpeg 或 image/webp的情况下,
+        // 可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
+        const dataUrl = canvas.toDataURL('image/jpeg', 0.8);
+        let newFile = dataURLtoFile(dataUrl, file.name);
+        resolve(newFile);
+      };
+    };
+  });
+}
+//  base64->file
+function dataURLtoFile(dataurl, fileName) {
+  let arr = dataurl.split(','),
+    mime = arr[0].match(/:(.*?);/)[1],
+    bstr = atob(arr[1]),
+    n = bstr.length,
+    u8arr = new Uint8Array(n);
+  while (n--) {
+    u8arr[n] = bstr.charCodeAt(n);
+  }
+  return new File([u8arr], fileName, { type: mime });
+}
+// base64->blob
+function dataURLtoBlob(dataurl) {
+  const arr = dataurl.split(','),
+    mime = arr[0].match(/:(.*?);/)[1],
+    bstr = atob(arr[1]);
+  let n = bstr.length;
+  const u8arr = new Uint8Array(n);
+  while (n--) {
+    u8arr[n] = bstr.charCodeAt(n);
+  }
+  return new Blob([u8arr], { type: mime });
+}