首页 > 其他分享 >vue3 vant4 h5图片上传时压缩

vue3 vant4 h5图片上传时压缩

时间:2024-04-30 14:12:38浏览次数:25  
标签:const img h5 width vant4 let file vue3 height

代码如下

upload组件的 afterRead 方法:

const afterRead = async file => {
  file.status = "uploading";
  file.message = "上传中...";
  const { data } = await upLoaderImg(file.file); //使用上传的方法。file.file
  if (data) {
    file.status = "done";
    // fileList.value.push(data);
  } else {
    file.status = "failed";
    file.message = "上传失败";
  }
};

共用文件中的方法如下:

export const upLoaderImg = async (file) => {
  let _file = file;
  const maxSize = 200;
  // 先压缩 再上传
  if (file.size / 1024 > maxSize) {
    const img = await readImg(file);
    const base64Data = compress(img);
    _file = dataURLtoFile(base64Data, file.name);
  }

  // file为 你读取成功的回调文件信息
  // new 一个FormData格式的参数
  let params = new FormData();
  params.append("file", _file);

  const config = {
    headers: {
      token: getToken()
    }
  };

  return new Promise((resolve, reject) => {
    axios
      .post(`${baseURL}/upload`, params, config)
      .then(res => {
        if (res && res.data && res.status === 200) {
          //如果为真 resolve出去
          if (res.data.data) {
            resolve(res.data);
          } else {
            showFailToast(res.data.message);
            resolve(res.data);
          }
        } else {
          //否则 showFailToast 提示
          showFailToast("请求失败");
          resolve({});
        }
      })
      .catch(err => {
        console.log("err", err);
        showFailToast("请求失败");
        resolve({});
      });
  });
};

const compress = img => {
  let initSize = img.src.length;
  let width = img.width;
  let height = img.height;

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

  let canvas = document.createElement("canvas"),
    ctx = canvas.getContext("2d");

  let tCanvas = document.createElement("canvas"),
    tctx = tCanvas.getContext("2d");

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

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

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

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

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

    for (let i = 0; i < count; i++) {
      for (let 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);
  }

  //进行最小压缩
  let 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;
};

// File文件转为base64
const readImg = file => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.onload = e => {
      // 创建一个Image对象
      const img = new Image();
      img.src = e.target.result;
      img.onload = () => {
        // 获取图片宽度和高度
        console.log(`图片宽度: ${img.width}, 图片高度: ${img.height}`);
        // return img;
        resolve(img);
      };
    };

    // 以DataURL的形式读取文件内容
    reader.readAsDataURL(file);
  });
};

//将base64转换为文件
const dataURLtoFile = (dataurl, filename) => {
  var 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 });
};

标签:const,img,h5,width,vant4,let,file,vue3,height
From: https://www.cnblogs.com/ZerlinM/p/18167925

相关文章

  • yarn + vue3 + vite 创建项目
      yarncreatevite//通过yarn+vite创建项目填写的创建的项目名称,默认名称vite-project 选择框架,我们点击上下键,回车选择,我们这里选择vue 选择语言,我们点击上下键,回车选择,我们这里选择TypeScript,即ts,然后回车 创建成功,如下 按照提示,执行命令cdvite-pr......
  • Vue3+Ts i18n实现国际化
    1、下载依赖npminstallvue-i18n@nex2、在src目录下创建文件夹创建文件index.ts、zh/index.ts、en/index.ts //index.tsimport{createI18n}from'vue-i18n'importzhfrom'./zh/index'importenfrom'./en/index'constmessages={en,zh,}......
  • 在vue2中,什么是双向绑定,为什么vue3要进行优化?
    一、什么是双向绑定我们先从单向绑定切入单向绑定非常简单,就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新双向绑定就很容易联想到了,在单向绑定的基础上,用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定举个栗子 当用户填写表单时,View......
  • vue3中ctrl加回车换行,光标位置设置
    <input v-model="text" type="textarea"@click="sbwz"@keydown="keysbwz" @keydown.enter.ctrl.exact.prevent="ctrlEnter" /> //暂存光标位置,后续截取换行使用consttextSplit=ref(0)//判断是否改变了上次光标位置constisTest=r......
  • vue3 把quill的base64变成图片地址
      你可以看看https://www.kancloud.cn/liuwave/quill/1434141或者看看别人的文章我的项目是vu3的 template的是这样的<el-form-itemlabel="中文详情"prop="content"><div><quill-editorref="QuillEditor"v-model:content="form.......
  • Vue3中SEO优化实践:利用unhead vue插件设置Mate标签
    我们在构建Vue3项目时,搜索引擎优化(SEO)是一个不可忽视的重要方面。优化网站结构、内容和代码,使其更符合搜索引擎的排名规则,对于提升网站曝光度和吸引更多用户至关重要。其中,设置合适的Mate标签(如标题、描述和关键词)是SEO优化的关键步骤之一。在Vue3项目中,我们可以利用unhead插件来......
  • uniapp+vue3聊天室|uni-app+vite4+uv-ui跨端仿微信app聊天语音/朋友圈
    原创研发uniapp+vue3+pinia2跨三端仿微信app聊天模板Uniapp-Wechat。uni-vue3-wchat基于uni-app+vue3+pinia2+uni-ui+uv-ui等技术跨端仿制微信App界面聊天项目,支持编译到H5+小程序端+App端。实现编辑框多行消息/emoj混合、长按触摸式仿微信语音面板、图片/视频预览、红包/朋友圈......
  • .h5ad数据结构解释(anndata 数据格式)
    官方网站:https://anndata.readthedocs.io/en/latest/下面的内容官网都有概述h5ad文件提供了一种可扩展的方式来记录数据及其注释(annotation),主要包含X,obs,var,uns等多个部分,分别存储不同的信息。结构如下图所示X是表达量矩阵,用来联系obs和var。具体来说X是一个稀疏......
  • CH592 CH582 CH573 蓝牙运行时调整RTC
    前言:CH592芯片在使用蓝牙外部32K精度比较高(根据选择的外部32.768K晶体,精度一般在20ppm以内)。直接使用内部32K不校准误差约为百分之二,校准后可以做到0.1%-0.3%精度。使用外部32K需要消耗一颗晶振的物料,同时芯片的相应GPIO会被占用。如果对于32K的误差要求不是很高,可以直接选择使......
  • 小程序微信及h5 发布流程
    微信小程序1先打包代码pnmpbuild:mp-wexin(package.json)2把代码上传到微信开发者工具3微信公众平台提交审核条件编译及h5注意:网页端不支持授权登录功能,通过条件编译进行不同平台条件编译语法:#ifdef或者#ifndef+平台名称;以#endif结尾(全局找wx.或者open-type......