最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue之原生上傳圖片加水印并壓縮圖片大小方式

 更新時(shí)間:2025年01月24日 16:41:32   作者:一朵野花壓海棠  
文章介紹了如何使用Vue原生上傳圖片,并在圖片上添加水印并壓縮圖片大小,首先,安裝了相應(yīng)的插件并進(jìn)行封裝,然后,介紹了添加水印的方法和上傳圖片的過(guò)程,最后,作者分享了自己的經(jīng)驗(yàn),并希望對(duì)大家有所幫助

vue原生上傳圖片加水印并壓縮圖片大小

安裝相應(yīng)插件

npm i -S  compressorjs
npm i -S  html2canvas

封裝添加水印的方法

import Compressor from "compressorjs";
import html2canvas from "html2canvas";

/**
 * 壓縮和旋轉(zhuǎn)圖片
 * @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;
      // 先縮放水印再轉(zhuǎn)成圖片
      markEle.style.transform = `scale(${scale})`;
      const markImg = await htmlToCanvas(markEle);

      // 先壓縮和旋轉(zhuǎn)圖片
      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);
    }
  });
}

上傳圖片,回顯圖片

<template>
  <div class="content-box">
    <div class="container">
      <div class="title">點(diǎn)擊上傳圖像(支持image/jpg,image/jpeg,image/png,image/gif格式圖片且大小不能超過(guò)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() {
      // 這個(gè)是元素dom節(jié)點(diǎn)
      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("圖片大小不能超過(guò)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; // 相當(dāng)于input里取得的files
      console.log(fileObj);
      let fd = new FormData(); // FormData 對(duì)象
      fd.append("file", fileObj); // 文件對(duì)象
      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>

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue請(qǐng)求后端接口導(dǎo)出excel表格方式

    Vue請(qǐng)求后端接口導(dǎo)出excel表格方式

    這篇文章主要介紹了Vue請(qǐng)求后端接口導(dǎo)出excel表格方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue 項(xiàng)目引入echarts 添加點(diǎn)擊事件操作

    vue 項(xiàng)目引入echarts 添加點(diǎn)擊事件操作

    這篇文章主要介紹了vue 項(xiàng)目引入echarts 添加點(diǎn)擊事件操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • vue 踩不完的異步之坑及解決

    vue 踩不完的異步之坑及解決

    這篇文章主要介紹了vue 踩不完的異步之坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 解決error?Couldn‘t?find?a?package.json?file?in報(bào)錯(cuò)的問(wèn)題

    解決error?Couldn‘t?find?a?package.json?file?in報(bào)錯(cuò)的問(wèn)題

    文章介紹了npm依賴包緩存導(dǎo)致重復(fù)下載的問(wèn)題,提供了刪除node_modules、清除緩存或重啟項(xiàng)目的解決方法,并附帶了查看npm緩存位置的命令
    2026-03-03
  • vue中的v-if和v-show的區(qū)別詳解

    vue中的v-if和v-show的區(qū)別詳解

    這篇文章主要介紹了vue中的v-if和v-show的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 詳細(xì)解讀VUE父子組件的使用

    詳細(xì)解讀VUE父子組件的使用

    這篇文章主要介紹了詳細(xì)解讀VUE父子組件的使用,今天來(lái)講一種子父組件深度耦合的方式,使我們不用額外的創(chuàng)建新的組件,也可以達(dá)到一些效果,下面與你們分享一下
    2023-05-05
  • Vue框架中正確引入JS庫(kù)的方法介紹

    Vue框架中正確引入JS庫(kù)的方法介紹

    最近在學(xué)習(xí)使用vue框架,在使用中遇到了一個(gè)問(wèn)題,查找相關(guān)資料終于找了正確的姿勢(shì),所以這篇文章主要給大家介紹了關(guān)于在Vue框架中正確引入JS庫(kù)的方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-07-07
  • vue3手動(dòng)設(shè)置滾動(dòng)條位置自動(dòng)定位功能

    vue3手動(dòng)設(shè)置滾動(dòng)條位置自動(dòng)定位功能

    這篇文章介紹了vue3手動(dòng)設(shè)置滾動(dòng)條位置自動(dòng)定位功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • Vue+Microapp實(shí)現(xiàn)微前端的示例詳解

    Vue+Microapp實(shí)現(xiàn)微前端的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何實(shí)現(xiàn)以vite+vue3+Microapp為主應(yīng)用,以vue2+element為子應(yīng)用的微前端,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下吧
    2023-06-06
  • 基于Vue3編寫一個(gè)打印模板設(shè)計(jì)器(print-canvas-designer)

    基于Vue3編寫一個(gè)打印模板設(shè)計(jì)器(print-canvas-designer)

    在業(yè)務(wù)系統(tǒng)里,標(biāo)簽打印存在一個(gè)常見(jiàn)弊端,它往往不是一次性的輸出功能,而是一套需要持續(xù)維護(hù)的編輯能力,本文將用 Vue3 做一個(gè)可擴(kuò)展的打印模板設(shè)計(jì)器,感興趣的小伙伴可以了解下
    2026-05-05

最新評(píng)論

梅河口市| 阿巴嘎旗| 安宁市| 华阴市| 辰溪县| 溧水县| 新建县| 大冶市| 庆元县| 桐城市| 从化市| 崇信县| 白玉县| 株洲市| 丘北县| 武邑县| 神池县| 民丰县| 博爱县| 柘荣县| 荆门市| 新建县| 阿克苏市| 临江市| 家居| 武冈市| 宜都市| 马鞍山市| 石城县| 崇义县| 泰来县| 蕉岭县| 舞阳县| 易门县| 衡阳市| 扶绥县| 特克斯县| 买车| 府谷县| 凤山市| 邵阳市|