vue之原生上传图片加水印并压缩图片大小方式

107 阅读2分钟

文章介绍了如何使用Vue原生上传图片,并在图片上添加水印并压缩图片大小,首先,安装了相应的插件并进行封装,然后,介绍了添加水印的方法和上传图片的过程,最后,作者分享了自己的经验,并希望对大家有所帮助

目录

**

GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!
【 如果你想靠AI翻身,你先需要一个靠谱的工具!  】

vue原生上传图片加水印并压缩图片大小

安装相应插件

``

````npm i -S  compressorjs`

`npm i -S  html2canvas`

封装添加水印的方法 ``


```js
```` import Compressor from  ``"compressorjs"``;`

` import html2canvas from  ``"html2canvas"``;`

 

`/**`

` ``* 压缩和旋转图片`

` ``* @param {blob} file`

` ``* @param {number} quality  压缩比例`

` ``* @param {number} maxWidth 图片最大宽度`

` ``* @returns {Promise}`

` ``*/`

` export  ``function` `compressor(file, drew, maxWidth = 750, quality = 0.6) {`

`  ``return` `new` `Promise((resolve) => {`

`    ``new` `Compressor(file, {`

`      `` strict:  ``false``,`

`      ``maxWidth,`

`      ``quality,`

`      ``drew,`

`      ``success: resolve,`

`      ``error(err) {`

`        ``console.log(err.message);`

`      ``},`

`    ``});`

`  ``});`

`}`

 

`/**`

` ``* 添加水印`

` ``* @param {blob} file`

` ``* @param {string} el`

` ``* @returns {Promise}`

` ``*/`

` export async  ``function` ` addWaterMarker(file, el =  ``"#markImg"`` , direction =  ``"rightDown"``) {`

`  ``return` `new` `Promise(async (resolve, reject) => {`

`    ``try` `{`

`      ``const maxWidth = 750;`

`      ``const img = await blobToImg(file);`

`      ``console.log(img.naturalWidth);`

`      ``const imgWidth = img.naturalWidth > maxWidth ? maxWidth : img.naturalWidth;`

 

`      ``// 生成水印图片`

`      ``const markEle = document.querySelector(el);`

`      ``const scale = (imgWidth * 0.25) / markEle.clientWidth;`

`      ``// 先缩放水印再转成图片`

`      ```markEle.style.transform = `scale(${scale})`;``

`      ``const markImg = await htmlToCanvas(markEle);`

 

`      ``// 先压缩和旋转图片`

`      ``file = await compressor(`

`        ``file,`

`        ``(context, canvas) => {`

`          ``if` ` (direction ==  ``"rightDown"``) {`

`            ``// 填充水印 右下角`

`            ``context.drawImage(markImg, canvas.width - markImg.width - 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height);`

`          `` }  ``else` `{`

`            ``// 填充水印 左下角`

`            ``context.drawImage(markImg, 15 * scale, canvas.height - markImg.height - 15 * scale, markImg.width, markImg.height);`

`          ``}`

`        ``},`

`        ``maxWidth`

`      ``);`

`      ``resolve(file);`

`    `` }  ``catch` `(error) {`

`      ``reject(error);`

`    ``}`

`  ``});`

`}`

 

`function` `blobToImg(blob) {`

`  ``return` `new` `Promise((resolve, reject) => {`

`    `` let reader =  ``new` `FileReader();`

`    ``reader.addEventListener(``"load"``, () => {`

`      `` let img =  ``new` `Image();`

`      ``img.src = reader.result;`

`      ``img.addEventListener(``"load"``, () => resolve(img));`

`    ``});`

`    ``reader.readAsDataURL(blob);`

`  ``});`

`}`

 

` export  ``function` ` htmlToCanvas(el, backgroundColor =  ``"rgba(0,0,0,.1)"``) {`

`  ``return` `new` `Promise(async (resolve, reject) => {`

`    ``try` `{`

`      ``const markImg = await html2canvas(el, {`

`        ``scale: 2,`

`        `` allowTaint:  ``false`` ,  ``//允许污染`

`        `` useCORS:  ``true``,`

`        `` backgroundColor,  ``//'transparent'  //背景色`

`      ``});`

`      ``resolve(markImg);`

`    `` }  ``catch` `(error) {`

`      ``reject(error);`

`    ``}`

`  ``});`

`}`

```js

上传图片,回显图片 ``

```<template>
  <div class="content-box">
    <div class="container">
      <div class="title">点击上传图像(支持image/jpg,image/jpeg,image/png,image/gif格式图片且大小不能超过10MB)</div>
      <div class="uploadImg">
        <span class="el-icon-plus"></span>
        <input :accept="accept" type="file" class="upload_ipu" ref="fileLoad" @change="uploadImg" />
      </div>
      <div class="imgList">
        <img v-if="imgShow" :src="imgSrc" />
      </div>
      <img v-if="imgShow" :src="fileUrl" />
      <!-- 图片上传水印 -->
      <div id="markImg">
        <div class="logo">
          图片水印:
          <img src="@/assets/logo.png" />
        </div>
        <p>文字水印:{{ loginName }}</p>
      </div>
    </div>
  </div>
</template>

<script>
import { compressor, addWaterMarker } from "../utils/imageUtils.js";
import apis from "@/api";
const {
  commonSys: { commonUploadFile },
} = apis;
export default {
  props: {
    accept: {
      type: String,
      default: "image/jpg,image/jpeg,image/png,image/gif",
    },
  },
  data() {
    return {
      imgShow: false,
      imgSrc: "",
      loginName: "fqniu",
      fileDate: new Date(),
      needWaterMark: true,
      fileUrl: "",
    };
  },
  // created() {
  //   this.parseTime = parseTime
  // },
  methods: {
    createUrl(file) {
      if (window.URL) {
        return window.URL.createObjectURL(file);
      } else if (window.webkitURL) {
        return window.webkitURL.createObjectURL(file);
      } else {
        return null;
      }
    },
    async uploadImg() {
      // 这个是元素dom节点
      console.log(this.$refs.fileLoad);
      // 上传文件fileList
      console.log(this.$refs.fileLoad.files);
      let file = this.$refs.fileLoad.files[0];
      let size = file.size / 1024 / 1024;
      console.log(file, file.lastModifiedDate);
      if (!this.accept.includes(file.type.toLowerCase())) {
        this.$message.error("图片格式不正确!");
        return false;
      }
      if (size > 10) {
        this.$message.error("图片大小不能超过10MB!");
        return false;
      }
      // 压缩图片
      // if (file.size > 512 * 1024 && file.type.includes("image/")) {
      //   file = await compressor(file);
      // }
      // 添加水印
      if (this.needWaterMark) {
        const fileName = file.name;
        file = await addWaterMarker(file, "#markImg", "leftDown");
        file.name = fileName;
      }
      this.imgSrc = this.createUrl(file);
      console.log(this.imgSrc);
      console.log(file);
      this.httpRequest(file);
      this.$message.success("上传成功!");
    },
    httpRequest(fileObj) {
      // let fileObj = param.file; // 相当于input里取得的files
      console.log(fileObj);
      let fd = new FormData(); // FormData 对象
      fd.append("file", fileObj); // 文件对象
      commonUploadFile("qms", fd).then((res) => {
        console.log(res.fileUrl);
        this.fileUrl = res.fileUrl;
        this.imgShow = true;
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.container {
  margin: 50px;
}
.title {
  font-size: 16px;
  color: #73777b;
}
.uploadImg {
  margin-top: 20px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 180px;
  height: 180px;
  transition: all 0.2s;
  background: #fff;
  &:hover {
    border-color: #409eff;
  }
  span {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }
  .upload_ipu {
    opacity: 0;
    width: 100%;
    height: 100%;
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    z-index: 2;
  }
  img {
    width: 178px;
    height: 178px;
    position: absolute;
    border-radius: 6px;
    left: 0;
    top: 0;
    z-index: 1;
  }
}
.imgList {
  width: 550px;
  height: 400px;
  img {
    width: 100%;
    height: 100%;
  }
}
// 水印样式
#markImg {
  position: absolute;
  left: -9999999px;
  text-align: left;
  padding: 10px 15px;
  .logo {
    font-weight: 600;
    font-size: 15px;
    color: #ffffff;
    display: flex;
    height: 21px;
    align-items: center;
    justify-content: flex-start;
    img {
      height: 21px;
      margin-right: 5px;
    }
  }
  p {
    margin-top: 6px;
    color: #ffffff;
    font-size: 12px;
    font-weight: 400;
  }
}
</style>

以上为个人经验,希望能给大家一个参考