基于canvas实现的图片加水印功能

开篇

本文内容基于工具小站-图片模块-图片加水印功能,对于此功能,简单做一个总结。

图片加水印功能实现逻辑

图片加水印功能分为两种:文字水印和图片水印功能。其中如果水印为文字类型,则使用ctx.fillText()方; 如果水印为图片类型,则使用ctx.drawImage()方法。

代码实现

<template>
  <div class="app-container">
    <header class="app-header">
      <h1>图片水印</h1>
      <p class="subtitle">为你的图片添加文字或图片水印</p>
    </header>

    <main class="main-content">
      <el-tabs v-model="activeTab" class="watermark-tabs">
        <el-tab-pane label="单张水印" name="single">
          <!-- 上传区域 -->
          <div class="upload-section" v-if="!currentImage">
            <el-upload
              class="upload-drop-zone"
              drag
              :auto-upload="false"
              accept="image/*"
              :show-file-list="false"
              @change="handleFileChange"
            >
              <el-icon class="upload-icon"><upload-filled /></el-icon>
              <div class="upload-text">
                <h3>将图片拖到此处,或点击上传</h3>
                <p>支持 PNG、JPG、WebP 等格式</p>
              </div>
            </el-upload>
          </div>

          <!-- 编辑区域 -->
          <div v-else class="edit-section">
            <div class="preview-area">
              <div class="canvas-container" ref="canvasContainer">
                <canvas ref="cacheCanvas" style="display: none"></canvas>
                <canvas
                  ref="canvas"
                  @mousedown="handleDrag"
                  @mousemove="handleDrag"
                  @mouseup="handleDrag"
                ></canvas>
              </div>
            </div>

            <div class="control-panel">
              <el-form :model="watermarkSettings" label-position="top">
                <!-- 水印类型选择 -->
                <el-form-item label="水印类型">
                  <el-radio-group v-model="watermarkSettings.type">
                    <el-radio label="text">文字水印</el-radio>
                    <el-radio label="image">图片水印</el-radio>
                  </el-radio-group>
                </el-form-item>

                <!-- 文字水印设置 -->
                <template v-if="watermarkSettings.type === 'text'">
                  <el-form-item label="水印文字">
                    <el-input
                      v-model="watermarkSettings.text"
                      placeholder="请输入水印文字"
                    />
                  </el-form-item>

                  <el-form-item label="字体">
                    <el-select v-model="watermarkSettings.fontFamily">
                      <el-option label="苹方" value="PingFang SC" />
                      <el-option label="黑体" value="SimHei" />
                      <el-option label="宋体" value="SimSun" />
                    </el-select>
                  </el-form-item>

                  <el-form-item label="字号">
                    <el-slider
                      v-model="watermarkSettings.fontSize"
                      :min="12"
                      :max="72"
                    />
                  </el-form-item>

                  <el-form-item label="颜色">
                    <el-color-picker v-model="watermarkSettings.color" />
                  </el-form-item>
                </template>

                <!-- 图片水印设置 -->
                <template v-if="watermarkSettings.type === 'image'">
                  <el-form-item label="水印图片">
                    <el-upload
                      class="watermark-image-upload"
                      :auto-upload="false"
                      accept="image/*"
                      :show-file-list="false"
                      @change="handleWatermarkImageChange"
                    >
                      <el-button type="primary">选择水印图片</el-button>
                    </el-upload>
                  </el-form-item>
                </template>

                <!-- 通用设置 -->
                <el-form-item label="透明度">
                  <el-slider
                    v-model="watermarkSettings.opacity"
                    :min="0"
                    :max="100"
                  />
                </el-form-item>

                <el-form-item label="位置">
                  <el-radio-group v-model="watermarkSettings.position">
                    <el-radio-button label="topLeft">左上</el-radio-button>
                    <el-radio-button label="topRight">右上</el-radio-button>
                    <el-radio-button label="bottomLeft">左下</el-radio-button>
                    <el-radio-button label="bottomRight">右下</el-radio-button>
                    <el-radio-button label="center">居中</el-radio-button>
                    <el-radio-button label="custom">自定义</el-radio-button>
                  </el-radio-group>
                </el-form-item>

                <div class="action-buttons">
                  <el-button
                    type="primary"
                    @click="applyWatermark"
                    :loading="processing"
                  >
                    应用水印
                  </el-button>
                  <el-button @click="resetImage">重新选择</el-button>
                  <el-button
                    type="success"
                    @click="downloadImage"
                    :disabled="!hasWatermark"
                  >
                    下载图片
                  </el-button>
                </div>
              </el-form>
            </div>
          </div>
        </el-tab-pane>

        <el-tab-pane label="批量水印" name="batch">
          <div class="batch-section">
            <div class="upload-section" v-if="!batchFiles.length">
              <el-upload
                class="upload-drop-zone"
                drag
                multiple
                :auto-upload="false"
                accept="image/*"
                :show-file-list="false"
                @change="handleBatchFilesChange"
              >
                <el-icon class="upload-icon"><upload-filled /></el-icon>
                <div class="upload-text">
                  <h3>将多张图片拖到此处,或点击上传</h3>
                  <p>支持 PNG、JPG、WebP 等格式</p>
                </div
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值