欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實(shí)現(xiàn)為圖片添加水印的方法詳解

 更新時間:2023年05月24日 09:24:02   作者:JYeontu  
在很多地方,我們都可以看到,上傳圖片的時候,圖片都會被加上默認(rèn)的水印,因此,我們在個人網(wǎng)站進(jìn)行圖片操作時,也可以給它加上自己獨(dú)特的水印,本文就為大家整理了JS添加圖片合文字水印的方法,需要的可以參考一下

背景

在很多地方,我們都可以看到,上傳圖片的時候,圖片都會被加上默認(rèn)的水印,水印的作用主要體現(xiàn)在以下幾個方面:

  • 1.版權(quán)保護(hù):在商業(yè)用途的照片中添加水印可以幫助保護(hù)作者的版權(quán),防止他人未經(jīng)授權(quán)使用照片。
  • 2.品牌推廣:將商業(yè)品牌、商標(biāo)或公司標(biāo)志添加到照片中,可以幫助提高品牌知名度和曝光率。
  • 3.防止盜版:添加水印可以防止盜版和未經(jīng)授權(quán)的使用,因?yàn)樗黠@表明該照片的版權(quán)歸原作者所有。
  • 4.標(biāo)識來源:在社交媒體平臺上分享照片時,添加水印可以幫助其他用戶識別出照片的來源和作者。
  • 5.識別真?zhèn)危簩τ谝恍┲匾恼掌蜃C件,如證書或合同等,加上水印可以幫助識別真?zhèn)危乐箓卧旌痛鄹摹?/li>

因此,我們在個人網(wǎng)站進(jìn)行圖片操作時,也可以給它加上自己獨(dú)特的水印,那么作為一名前端開發(fā),我們該如何實(shí)現(xiàn)給圖片加上水印呢?

實(shí)現(xiàn)

對圖片進(jìn)行處理,我們的首選當(dāng)然是canvas啦,使用canvas我們可以便捷地對圖片進(jìn)行操作,我們需要操作的圖片主要分為以下兩種:

  • 1、本地上傳的圖片
  • 2、線上鏈接圖片

file 轉(zhuǎn) base64

對于本地上傳的圖片,我們需要先將其轉(zhuǎn)換成 base64 再進(jìn)行后續(xù)處理:

我們可以通過FileReader來獲取圖片的 base64,F(xiàn)ileReader 是一種異步讀取文件機(jī)制。

FileReader 提供了如下方法:

  • readAsArrayBuffer(file):按字節(jié)讀取文件內(nèi)容,結(jié)果用 ArrayBuffer 對象表示
  • readAsBinaryString(file):按字節(jié)讀取文件內(nèi)容,結(jié)果為文件的二進(jìn)制串
  • readAsDataURL(file):讀取文件內(nèi)容,結(jié)果用 data:url 的字符串形式表示
  • readAsText(file,encoding):按字符讀取文件內(nèi)容,結(jié)果用字符串形式表示
  • abort():終止文件讀取操作

readAsDataURL 方法會讀取指定的 Blob 或 File 對象。并生成 data URl(base64 編碼)。這里我們可以使用readAsDataURL來獲取上傳圖片的 base64 編碼:

function fileToBase64Async(file) {
  return new Promise((resolve, reject) => {
    let reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = (e) => {
      resolve(e.target.result);
    };
  });
}

使用 canvas 給圖片加水印

使用在線圖片鏈接的時候需要注意給圖片設(shè)置crossOrigin屬性(img.setAttribute("crossOrigin",'Anonymous')),不然會出現(xiàn)以下錯誤:

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

大概意思是 canvas 無法執(zhí)行 toDataURL 方法:污染的畫布無法輸出。受限于 CORS 策略,會存在跨域問題,雖然可以使用圖像(比如 append 到頁面上)但是繪制到畫布上會污染畫布,一旦一個畫布被污染,就無法提取畫布的數(shù)據(jù),比如無法使用使用畫布 toBlob(),toDataURL(),或 getImageData()方法;當(dāng)使用這些方法的時候 會拋出一個安全錯誤。

我們這里可以分為文字水印和圖片水印兩種:

文字水印

添加文字水印的大致步驟如下:

1、生成一個新的 canvas 畫布;

const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;

2、將現(xiàn)有需要添加水印的圖片繪制到畫布上;

const ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

3、繪制需要添加的水印文本并設(shè)置樣式。

我們可以使用fillText和strokeText這兩個方法來繪制文字,fillText繪制的是默認(rèn)的普通實(shí)線文本,strokeText繪制的是描邊文本,這里我使用了strokeText來進(jìn)行水印文本繪制。

完整代碼如下:

const remFontSize = canvas.width / 35;
ctx.font = "bolder " + remFontSize + "px Verdana";
ctx.textAlign = "center";
ctx.strokeStyle = "#fff";
const name = "@JYeontu";
const spaceH = remFontSize * 0.3;
ctx.strokeText(name, canvas.width / 2, canvas.height - remFontSize - spaceH);
function fillTextToImg(base64) {
  const img = new Image();
  img.src = base64;
  img.setAttribute("crossOrigin", "Anonymous");
  return new Promise((resolve, reject) => {
    img.onload = () => {
      const canvas = document.createElement("canvas");
      canvas.width = img.width;
      canvas.height = img.height;
      const ctx = canvas.getContext("2d");
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      const remFontSize = canvas.width / 35;
      ctx.font = "bolder " + remFontSize + "px Verdana";
      ctx.textAlign = "center";
      /**
        ctx.textAlign = "center|end|left|right|start";
        start:默認(rèn),文本在指定的位置開始。
        end:文本在指定的位置結(jié)束。
        center:文本的中心在指定的位置。
        left:文本左對齊。
        right:文本右對齊。
        **/
      ctx.strokeStyle = "#fff";
      const name = "@JYeontu";
      const spaceH = remFontSize * 0.3;
      ctx.strokeText(
        name,
        canvas.width / 2,
        canvas.height - remFontSize - spaceH
      );
      resolve(canvas.toDataURL("image/jpeg"));
    };
  });
}

效果如下圖,左邊為原圖,右邊為加了文字水印的圖片:

圖片水印

//圖片轉(zhuǎn)為base64
async function getImgBase64(base64, width = 50) {
  const img = new Image();
  img.src = base64;
  img.setAttribute("crossOrigin", "Anonymous");
  return new Promise((resolve, reject) => {
    img.onload = () => {
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");
      canvas.width = width;
      canvas.height = (img.height * width) / img.width;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      resolve(canvas.toDataURL("image/jpeg"));
    };
  });
}
function fillImgToImg(base64, waterMark = imgLink) {
  waterMark =
    "https://img2.baidu.com/it/u=2243573419,589412055&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1684861200&t=7bf0a17ca21ae8ec8aa77b0f98cb4c7e";
  const img = new Image();
  img.src = base64;
  img.setAttribute("crossOrigin", "Anonymous");
  return new Promise((resolve, reject) => {
    img.onload = async () => {
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      const waterMarkSrc = await getImgBase64(waterMark, 100);
      const waterMarkImg = new Image();
      waterMarkImg.src = waterMarkSrc;
      waterMarkImg.setAttribute("crossOrigin", "Anonymous");
      waterMarkImg.onload = () => {
        ctx.drawImage(
          waterMarkImg,
          canvas.width / 2 - waterMarkImg.width / 2,
          canvas.height - waterMarkImg.height - 10,
          waterMarkImg.width,
          waterMarkImg.height
        );
        resolve(canvas.toDataURL("image/jpeg"));
      };
    };
  });
}

效果如下圖,左邊為原圖,右邊為加了圖片水印的圖片: 

完整代碼

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      img {
        width: 500px;
      }
    </style>
  </head>
  <body>
    <input type="file" id="fileUplodBox" />
    <img alt="原圖" id="originPic" />
    <img alt="水印圖" id="waterMark" />
  </body>
  <script>
    const imgLink =
      "https://img2.baidu.com/it/u=2048195462,703560066&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1684861200&t=a0c977f68632303e7dac2196e8ad2866";
    document.getElementById("originPic").setAttribute("src", imgLink);
    const fileUplodBox = document.getElementById("fileUplodBox");
    fileUplodBox.addEventListener("change", (e) => {
      const file = e.target.files[0];
      dealFile(file);
    });
    test();
    async function test() {
      const img = await fillImgToImg(imgLink);
      document.getElementById("waterMark").setAttribute("src", img);
    }
    async function dealFile(file) {
      const base64 = await fileToBase64Async(file);
      document.getElementById("originPic").setAttribute("src", base64);
      const img = await fillTextToImg(base64);
      document.getElementById("waterMark").setAttribute("src", img);
    }
    function fileToBase64Async(file) {
      return new Promise((resolve, reject) => {
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => {
          resolve(e.target.result);
        };
      });
    }
    // 給圖片加文字水印
    function fillTextToImg(base64) {
      const img = new Image();
      img.src = base64;
      img.setAttribute("crossOrigin", "Anonymous");
      return new Promise((resolve, reject) => {
        img.onload = () => {
          const canvas = document.createElement("canvas");
          const ctx = canvas.getContext("2d");
          canvas.width = img.width;
          canvas.height = img.height;
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
          const remFontSize = canvas.width / 35;
          ctx.font = "bolder " + remFontSize + "px Verdana";
          ctx.textAlign = "center";
          ctx.strokeStyle = "#fff";
          const uploadTime = new Date();
          const name = "@JYeontu";
          const spaceH = remFontSize * 0.3;
          ctx.strokeText(
            name,
            canvas.width / 2,
            canvas.height - remFontSize - spaceH
          );
          resolve(canvas.toDataURL("image/jpeg"));
        };
      });
    }
    async function getImgBase64(base64, width = 50) {
      const img = new Image();
      img.src = base64;
      img.setAttribute("crossOrigin", "Anonymous");
      return new Promise((resolve, reject) => {
        img.onload = () => {
          const canvas = document.createElement("canvas");
          const ctx = canvas.getContext("2d");
          canvas.width = width;
          canvas.height = (img.height * width) / img.width;
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
          resolve(canvas.toDataURL("image/jpeg"));
        };
      });
    }
    // 給圖片加圖片水印
    function fillImgToImg(base64, waterMark = imgLink) {
      waterMark =
        "https://img2.baidu.com/it/u=2243573419,589412055&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1684861200&t=7bf0a17ca21ae8ec8aa77b0f98cb4c7e";
      const img = new Image();
      img.src = base64;
      img.setAttribute("crossOrigin", "Anonymous");
      return new Promise((resolve, reject) => {
        img.onload = async () => {
          const canvas = document.createElement("canvas");
          const ctx = canvas.getContext("2d");
          canvas.width = img.width;
          canvas.height = img.height;
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
          const waterMarkSrc = await getImgBase64(waterMark, 100);
          const waterMarkImg = new Image();
          waterMarkImg.src = waterMarkSrc;
          waterMarkImg.setAttribute("crossOrigin", "Anonymous");
          waterMarkImg.onload = () => {
            ctx.drawImage(
              waterMarkImg,
              canvas.width / 2 - waterMarkImg.width / 2,
              canvas.height - waterMarkImg.height - 10,
              waterMarkImg.width,
              waterMarkImg.height
            );
            resolve(canvas.toDataURL("image/jpeg"));
          };
        };
      });
    }
  </script>
</html>

以上就是JavaScript實(shí)現(xiàn)為圖片添加水印的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于JavaScript圖片添加水印的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論