Implement image text watermark generator based on canvas

introduce

In front-end development, we often encounter the function of adding watermarks to pictures. Just like when creating csdn articles, the pictures uploaded will be marked with the uploader's watermark. Let's explore how this watermark is generated.

 The text watermark generated first can probably control the color, font size, and position of the watermark, etc.

1. Static page structure

We will simply build a static page with a watermark generator

<!DOCTYPE html>
<html>

<head>
  <title>图片水印生成器</title>
  <style>
    .container {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    #watermark {
      position: relative;
    }

    #downloadBtn {
      margin-top: 10px;
      padding: 5px 10px;
      background-color: #4CAF50;
      color: white;
      border: none;
      cursor: pointer;
      display: none;
    }
  </style>
</head>

<body>
  <div class="container">
    <h2>图片水印生成器</h2>
    <input type="file" id="fileInput">
    <br>
    <label for="text">水印文字:</label>
    <input type="text" id="text">
    <br>
    <label for="size">文字大小:</label>
    <input type="number" id="size">
    <br>
    <label for="color">文字颜色:</label>
    <input type="color" id="color">
    <br>
    <label for="position">水印位置:</label>
    <select id="position">
      <option value="top-left">左上角</option>
      <option value="top-right">右上角</option>
      <option value="bottom-left">左下角</option>
      <option value="bottom-right">右下角</option>
      <option value="center">居中</option>
    </select>
    <br>
    <button id="generateBtn">生成水印</button>
    <a href="#" id="downloadBtn" download="watermarked_image.png">下载水印图片</a>
    <br>
    <img id="watermark" src="" alt="水印图片">
  </div>
</body>

</html>

The static page probably looks like this

Next is the js code

2. Bind the click event to the generate watermark button

 First, you need to get the button that generates the watermark and bind a click event to it.

  document.getElementById('generateBtn').addEventListener('click', generateWatermark);
    //点击后调用此函数生成水印

3. Function to generate watermark

First, you need to get the DOM of the value you need to use.

 const obj = {
        text: document.getElementById('text').value,
        size: document.getElementById('size').value,
        color: document.getElementById('color').value,
        position: document.getElementById('position').value
      }

Read the file of the image uploaded by the user

const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const reader = new FileReader(); //获取一个FileReader对象,用于读取上传的图片文件。

Events triggered after the binding file is read

reader.onload = (event) => { //当文件读取完成后触发
        const img = new Image(); //创建一个Image对象,用于加载上传的图片文件
        img.onload = () => { //当图片加载完成后触发
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = img.width; //canvas画布的width和height就是图片的宽和高
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0); //将上传的图片绘制到canvas上
        }
    };

This is constructed using canvas, set the width and height of the canvas to the size of the image, and then paste the image onto the canvas.

 The next step is to set the size, color, and position of the text.

          ctx.font = obj.size + 'px Arial'; //设置canvas上文字的字体大小和颜色
          ctx.fillStyle = obj.color;
          console.log(obj.position);
          switch (obj.position) {
            case 'top-left':
              ctx.fillText(obj.text, 10, 30)
              break
            case 'top-right':
              ctx.fillText(obj.text, canvas.width - 10 - ctx.measureText(obj.text).width, 30)
              break
            case 'bottom-left':
              ctx.fillText(obj.text, 10, canvas.height - 10)
              break
            case 'bottom-right':
              ctx.fillText(obj.text, canvas.width - 10 - ctx.measureText(obj.text).width, canvas.height - 10)
              break
            case 'center':
              const textWidth = ctx.measureText(obj.text).width
              const textHeight = 20 // Assuming font size is 20px
              const centerX = (canvas.width - textWidth) / 2
              const centerY = (canvas.height + textHeight) / 2
              ctx.fillText(obj.text, centerX, centerY)
              break
          }

My text position is set to the four corners and the middle. This position can be determined according to the actual situation.

The text position calculation method also uses ctx.measureText()

The key code is to paste text on the picture

ctx.fillText(obj.text, centerX, centerY)

The last step is to change the src attribute of the initial img tag to display it and provide a download button.

const watermarkedImage = new Image();
          //将canvas转换为DataURL,以便稍后使用。
          watermarkedImage.src = canvas.toDataURL();
          //将水印图片的src属性设置为canvas转换后的DataURL
          document.getElementById('watermark').src = watermarkedImage.src;
          //将下载按钮的display属性设置为'inline-block',以便在canvas下方显示用于下载图片
          document.getElementById('downloadBtn').href = watermarkedImage.src;
          document.getElementById('downloadBtn').style.display = 'inline-block';
        };
        img.src = event.target.result;
      };
      reader.readAsDataURL(file);

You can now upload images to generate watermarks

Download function is also available

4. Complete code

<!DOCTYPE html>
<html>

<head>
  <title>图片水印生成器</title>
  <style>
    .container {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    #watermark {
      position: relative;
    }

    li {
      list-style: none;
    }


    #downloadBtn {
      margin-top: 10px;
      padding: 5px 10px;
      background-color: #4CAF50;
      color: white;
      border: none;
      cursor: pointer;
      display: none;
    }
  </style>
</head>

<body>
  <div class="container">
    <h2>图片水印生成器</h2>
    <input type="file" id="fileInput">
    <br>
    <label for="text">水印文字:</label>
    <input type="text" id="text">
    <br>
    <label for="size">文字大小:</label>
    <input type="number" id="size">
    <br>
    <label for="color">文字颜色:</label>
    <input type="color" id="color">
    <br>
    <label for="position">水印位置:</label>
    <select id="position">
      <option value="top-left">左上角</option>
      <option value="top-right">右上角</option>
      <option value="bottom-left">左下角</option>
      <option value="bottom-right">右下角</option>
      <option value="center">居中</option>
    </select>
    <br>
    <button id="generateBtn">生成水印</button>
    <a href="#" id="downloadBtn" download="watermarked_image.png">下载水印图片</a>
    <br>
    <img id="watermark" src="" alt="水印图片">
  </div>

  <script>
    document.getElementById('generateBtn').addEventListener('click', generateWatermark);
    //点击后调用此函数生成水印

    function generateWatermark() {
      //获取到input框中的一些值
      const obj = {
        text: document.getElementById('text').value,
        size: document.getElementById('size').value,
        color: document.getElementById('color').value,
        position: document.getElementById('position').value
      }
      const fileInput = document.getElementById('fileInput');
      const file = fileInput.files[0];
      const reader = new FileReader(); //获取一个FileReader对象,用于读取上传的图片文件。

      reader.onload = (event) => { //当文件读取完成后触发
        const img = new Image(); //创建一个Image对象,用于加载上传的图片文件
        img.onload = () => { //当图片加载完成后触发
          const canvas = document.createElement('canvas');
          const ctx = canvas.getContext('2d');
          canvas.width = img.width; //canvas画布的width和height就是图片的宽和高
          canvas.height = img.height;
          ctx.drawImage(img, 0, 0); //将上传的图片绘制到canvas上

          ctx.font = obj.size + 'px Arial'; //设置canvas上文字的字体大小和颜色
          ctx.fillStyle = obj.color;
          console.log(obj.position);
          switch (obj.position) {
            case 'top-left':
              ctx.fillText(obj.text, 10, 30)
              break
            case 'top-right':
              ctx.fillText(obj.text, canvas.width - 10 - ctx.measureText(obj.text).width, 30)
              break
            case 'bottom-left':
              ctx.fillText(obj.text, 10, canvas.height - 10)
              break
            case 'bottom-right':
              ctx.fillText(obj.text, canvas.width - 10 - ctx.measureText(obj.text).width, canvas.height - 10)
              break
            case 'center':
              const textWidth = ctx.measureText(obj.text).width
              const textHeight = 20 // Assuming font size is 20px
              const centerX = (canvas.width - textWidth) / 2
              const centerY = (canvas.height + textHeight) / 2
              ctx.fillText(obj.text, centerX, centerY)
              break
          }
          // ctx.fillText(obj.text, 30, 30);

          const watermarkedImage = new Image();
          //将canvas转换为DataURL,以便稍后使用。
          watermarkedImage.src = canvas.toDataURL();
          //将水印图片的src属性设置为canvas转换后的DataURL
          document.getElementById('watermark').src = watermarkedImage.src;
          //将下载按钮的display属性设置为'inline-block',以便在canvas下方显示用于下载图片
          document.getElementById('downloadBtn').href = watermarkedImage.src;
          document.getElementById('downloadBtn').style.display = 'inline-block';
        };
        img.src = event.target.result;
      };
      reader.readAsDataURL(file);
    }
  </script>
</body>

</html>

Summarize

The main core logic is actually very simple, that is, use canvas to paste the image onto the canvas, then set the color, font size and other attributes of the text watermark, paste it to the corresponding position on the canvas, and finally change the src of the original img. Properties to display watermark images.

Guess you like

Origin blog.csdn.net/m0_64642443/article/details/132788360