基于canvas给图片添加水印

  • 实现效果图
  • 图片添加水印的步骤
    • 1.获取图片路径,将图片转换为canvas
    • 2.canvas画布上绘制文字水印
    • 3.水印绘制完成后,将canvas转换为图片格式
    • 4.水印绘制完成后,将canvas下载为图片
  • 完整代码总结
    • 1、在utils.js 封装添加水印的通用方法,将以上方法export导出
    • 2、在页面import 导入方法并调用

实现效果图

图片添加水印的步骤

  1. 获取图片路径,将图片转换为canvas
  2. canvas画布上绘制文字水印
  3. 预览:水印绘制完成后,将canvas转换为图片格式
  4. 下载:水印绘制完成后,将canvas下载为图片

1.获取图片路径,将图片转换为canvas

/*** 图片路径转成canvas* @param {图片url} url*/
async function imgToCanvas(url) {// 创建img元素const img = document.createElement("img");img.src = url;img.setAttribute("crossOrigin", "anonymous"); // 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.await new Promise((resolve) => (img.onload = resolve));// 创建canvas DOM元素,并设置其宽高和图片一样const canvas = document.createElement("canvas");canvas.width = img.width;canvas.height = img.height;// 坐标(0,0) 表示从此处开始绘制,相当于偏移。canvas.getContext("2d").drawImage(img, 0, 0);return canvas;
}

2.canvas画布上绘制文字水印

/*** 画布添加水印*/
const drawWaterMark = ({ canvas, textArray, fontFamily = "microsoft yahei", fontSize, fontcolor = "#dadbdc", rotate = 30, textAlign = "left", density = 2.0 }) => {const ctx = canvas.getContext("2d");let imgWidth = canvas.width;let imgHeight = canvas.height;ctx.font = `${fontSize}px ${fontFamily}`;ctx.lineWidth = 1;ctx.fillStyle = fontcolor;ctx.textAlign = textAlign;ctx.textBaseline = "middle";// //文字坐标const maxPx = Math.max(imgWidth, imgHeight);const stepPx = Math.floor(maxPx / density);let arrayX = [0]; //初始水印位置 canvas坐标 0 0 点while (arrayX[arrayX.length - 1] < maxPx / 2) {arrayX.push(arrayX[arrayX.length - 1] + stepPx);}arrayX.push(...arrayX.slice(1, arrayX.length).map((el) => {return -el;}));for (let i = 0; i < arrayX.length; i++) {for (let j = 0; j < arrayX.length; j++) {ctx.save();ctx.translate(imgWidth / 2, imgHeight / 2); ///画布旋转原点 移到 图片中心// ctx.rotate(-Math.PI / 5);ctx.rotate((Math.PI / 120) * -rotate);if (textArray.length > 3) {//最多显示三行水印,也可以根据需要自定义textArray = textArray.slice(0, 3);}textArray.forEach((el, index) => {let offsetY = fontSize * index + 2;ctx.fillText(el, arrayX[i], arrayX[j] + offsetY);});ctx.restore();}}
};

3.水印绘制完成后,将canvas转换为图片格式

/*** canvas转成img* @param {canvas对象} canvas*/
export function canvasToImg({canvas, maxWidth = "100%", maxHeight = "100%"}) {// 新建Image对象,可以理解为DOMvar image = new Image();// canvas.toDataURL 返回的是一串Base64编码的URL// 指定格式 PNGimage.src = canvas.toDataURL("image/png");image.style.maxHeight = maxHeight;image.style.maxWidth = maxWidth;return image;
}

4.水印绘制完成后,将canvas下载为图片

/*** 下载canves为图片* @param {canvas对象} canvas* @param {文件名} filename*/
export function downloadCanves(canvas, filename = "下载") {let base64 = canvas.toDataURL("image/png");let blob = dataURItoBlob(base64);const a = document.createElement("a"); // 动态创建a标签,防止下载大文件时,用户没看到下载提示连续点击const url = window.URL.createObjectURL(blob);a.href = url;a.download = filename;a.click();window.URL.revokeObjectURL(url);
}

完整代码总结

1、在utils.js 封装添加水印的通用方法,将以上方法export导出

/*** 图片路径转成canvas* @param {图片url} url*/
export async function imgToCanvas(url) {// 创建img元素const img = document.createElement("img");img.src = url;img.setAttribute("crossOrigin", "anonymous"); // 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.await new Promise((resolve) => (img.onload = resolve));// 创建canvas DOM元素,并设置其宽高和图片一样const canvas = document.createElement("canvas");canvas.width = img.width;canvas.height = img.height;// 坐标(0,0) 表示从此处开始绘制,相当于偏移。canvas.getContext("2d").drawImage(img, 0, 0);return canvas;
}
/*** 画布添加水印*/
export const drawWaterMark = ({ canvas, textArray, fontFamily = "microsoft yahei", fontSize, fontcolor = "#dadbdc", rotate = 30, textAlign = "left", density = 2.0 }) => {const ctx = canvas.getContext("2d");let imgWidth = canvas.width;let imgHeight = canvas.height;ctx.font = `${fontSize}px ${fontFamily}`;ctx.lineWidth = 1;ctx.fillStyle = fontcolor;ctx.textAlign = textAlign;ctx.textBaseline = "middle";// //文字坐标const maxPx = Math.max(imgWidth, imgHeight);const stepPx = Math.floor(maxPx / density);let arrayX = [0]; //初始水印位置 canvas坐标 0 0 点while (arrayX[arrayX.length - 1] < maxPx / 2) {arrayX.push(arrayX[arrayX.length - 1] + stepPx);}arrayX.push(...arrayX.slice(1, arrayX.length).map((el) => {return -el;}));for (let i = 0; i < arrayX.length; i++) {for (let j = 0; j < arrayX.length; j++) {ctx.save();ctx.translate(imgWidth / 2, imgHeight / 2); ///画布旋转原点 移到 图片中心// ctx.rotate(-Math.PI / 5);ctx.rotate((Math.PI / 120) * -rotate);if (textArray.length > 3) {//最多显示三行水印,也可以根据需要自定义textArray = textArray.slice(0, 3);}textArray.forEach((el, index) => {let offsetY = fontSize * index + 2;ctx.fillText(el, arrayX[i], arrayX[j] + offsetY);});ctx.restore();}}
};/*** canvas转成img* @param {canvas对象} canvas*/
export function canvasToImg({canvas, maxWidth = "100%", maxHeight = "100%"}) {// 新建Image对象,可以理解为DOMvar image = new Image();// 指定格式 PNG; canvas.toDataURL 返回的是一串Base64编码的URLimage.src = canvas.toDataURL("image/png");image.style.maxHeight = maxHeight;image.style.maxWidth = maxWidth;return image;
}
/*** 下载canves为图片* @param {canvas对象} canvas* @param {文件名} filename*/
export function downloadCanves(canvas, filename = "下载") {let base64 = canvas.toDataURL("image/png");let blob = dataURItoBlob(base64);const a = document.createElement("a"); // 动态创建a标签,防止下载大文件时,用户没看到下载提示连续点击const url = window.URL.createObjectURL(blob);a.href = url;a.download = filename;a.click();window.URL.revokeObjectURL(url);
}

2、在页面import 导入方法并调用

<template><!-- 水印图片预览 --><div class="content"><div class="imageBox" id="imageBox"></div><el-button type="primary" @click="downFile" style="margin-top: 10px; width: 100px">下 载</el-button></div>
</template><script>
import {  drawWaterMark, imgToCanvas, canvasToImg, downloadCanves } from "@/utils/fileUtils.js";
export default {data() {return {fileUrl:"XXXX.jpg",fontSize: 50,objmsg: {canvas: null, //canvas  [必传]textArray: ["水印图片", "2022-01-01"], // /水印文字 数组类型  最大三行  [必传]fontFamily: "fangsong", // 默认 microsoft yaheifontSize: 30, //字体大小 默认 #dadbdcfontcolor: "#fff", //字体颜色   默认 #dadbdcrotate: 30, //旋转角度   数字类型textAlign: "center", //水印文字居中方式:left center right  默认 leftdensity: 3.0, // 稠密度},};},mounted() {this.drawWaterMarkFn();// 添加水印},methods: {// 图片添加水印async drawWaterMarkFn() {// 1.图片路径转成canvasconst tempCanvas = await imgToCanvas(this.fileUrl);this.objmsg.canvas = tempCanvas // 2.canvas添加水印drawWaterMark(this.objmsg);// 3.canvas转成imgconst waterImage = await canvasToImg({canvas: tempCanvas,maxWidth: "650px", // 最大宽度maxHeight: "650px", // 最大高度});// 查看效果var Box = document.getElementById("imageBox");Box.appendChild(waterImage);},// 下载添加水印的图片async downFile() {// 1.图片路径转成canvasconst tempCanvas = await imgToCanvas(this.fileUrl);this.objmsg.canvas = tempCanvas // 2.canvas添加水印await drawWaterMark(this.objmsg);// 3.下载加水印后的图片downloadCanves(tempCanvas,  "水印图片下载");},},
};
</script><style lang="scss" scoped>
.waterMakerinfo {.content {text-align: center;::v-deep .imageBox {max-height: 650px;min-height: 500px;.img {width: 100%;height: 100%;}}}::v-deep {.el-dialog__footer {text-align: right !important;position: absolute;width: 200px;top: unset;right: 20px;bottom: 0px;padding: 10px !important;padding-left: 20px !important;background-color: transparent !important;z-index: 99;}}
}
</style>

JS前端基于canvas给图片添加水印,并下载带有水印的图片相关推荐

  1. 前端实现可绘制的canvas画布_JS前端基于canvas给图片添加水印

    前两天给个人网站添加了一个小功能,就是在文章编辑上传图片的时候自动给图片加上水印.给网页图片添加水印是个常见的功能,也是互联网内容作者保护自己版权的方法之一.本文简单记录一下借助canvas在前端实现 ...

  2. 给图片添加多条文字水印和图片水印

    原始图: 水印原始模板: 添加水印后的效果图 package com.sjaco.hy.api.test;import java.awt.image.BufferedImage; import jav ...

  3. html中钟表功能的js插件,基于canvas的15种不同外观时钟js插件

    CanvasClock是一款基于Canvas的纯js时钟插件.该js时钟插件可以通过配置参数来生成15种不同外观的时钟.它使用纯js来制作,没有使用任何css代码和外部依赖. 使用方法 在页面引入ca ...

  4. PHP用gd库给图片添加水印,php用GD库给图片添加水印

    php用GD库给图片添加文字水印,整个代码比较简单,DEMO如下: /*打开图片*/ //1.配置图片路径 $src = "aeroplane.jpg"; //2.获取图片信息 $ ...

  5. C# 处理PPT水印(一)——添加水印效果(文字水印、图片水印)

    对文档添加水印可以有效声明和保护文档,是保护重要文件的方式之一.在PPT文档中同样也可以设置水印,包括文本水印和图片水印,本文将讲述如何通过Spire.Presentation for .NET来对P ...

  6. java word 添加水印图片_Java添加Word文本水印和图片水印

    水印是一种常用于各种文档的声明.防伪手段,一般可设置文字水印或者加载图片作为水印.以下内容将分享通过Java编程给Word文档添加水印效果的方法,即 文本水印 图片水印 使用工具:Free Spire ...

  7. uni-app APP,H5图片上传添加文字水印,图片只显示左上角bug(H5,安卓App可用,其他暂未测试)

    项目场景: 提示:这里简述项目相关背景: uni-app上传图片添加文字水印功能时图片只显示左上角,或者图片重叠 图片不规则一系列bug,特此记录 问题描述 提示:这里描述项目中遇到的问题: 上传图片 ...

  8. 新生研讨课:利用OpenCV处理带有水印的图片的调研报告

    电子科技大学 格拉斯哥学院 2017级 2017200602038 席文骥 目录 1.引言 2.技术背景 3.具体问题 4.实现方法 5.结语 6.参考 1.引言 在我们学院去年开设的新生研讨课上,曾 ...

  9. 怎样边下载宝贝图片边给图片添加自己的文字水印或图片水印

    今天小编要介绍一个比较常用的技巧,就是如何在下载商品图片时,给商品主图添加一些个性的水印或文字?一起来看看具体的操作步骤吧. 首先复制要抓取的商品链接地址 小编使用的下载图片工具(载图助手),打开进入 ...

最新文章

  1. command对象提供的3个execute方法是_前阿里P9的Java面试重点3:多线程
  2. 如何生成自己的Yaas Service yaas
  3. 2010 本年度认证目标:坐沙发的熊
  4. Python爬虫:爬取instagram,破解js加密参数
  5. 28 CO配置-控制-产品成本控制-成本对象控制-期末结算-定义行标识
  6. VUE中出现 Cannot read property ‘length‘ of undefined 的错误
  7. Cocos2d-X-3.0之后的版本的环境搭建
  8. Mac Navicat Premium 12.1.13 破解版本下载
  9. boost电路输出电流公式_boost计算公式
  10. 黑洞照片打印是用超级计算机,给黑洞冲洗一张照片,怎么就用了两年时间 | 科技向未来...
  11. 图说: 量子物理学的主要内容
  12. java 图片 加边框_给图片加图片边框 图片边框要求为PNG格式
  13. Protobuf 介绍与实战21:如何生成一维数组、二维数组(repeated数组类型介绍)
  14. Matlab GUI编程技巧(十七):Matlab GUI设计总结
  15. mysql查询提示_MySQL自成一派的查询提示
  16. 9大常见光固化3D打印树脂分析
  17. 易语言 网页_取文本_reg的源码
  18. matlab求偏转角,轮胎的回正力矩——侧偏角特性计算实例
  19. (八)JVM成神路之GC分区篇:G1、ZGC、ShenandoahGC高性能收集器深入剖析
  20. 怎样隐藏计算机中的文件夹,电脑上的文件夹不想被别人看到怎么办?如何隐藏电脑文件夹?-电脑文件夹怎么加密...

热门文章

  1. 【翻译】Batch Normalization: Accelerating Deep Network Trainingby Reducing Internal Covariate Shift
  2. 页面错误!请稍后再试~ thinkphp
  3. 获取系统时间及将时间戳转化为时间
  4. -XX:MaxDirectMemorySize
  5. 一、R语言Task View--Spatial 空间数据分析
  6. 【Vue基础】Vue基础自测45题
  7. element-ui(vue)表格的自定义标题,逻辑判断
  8. ubuntu使用fail2ban_Ubuntu Server 18.04上安装fail2ban
  9. 2021北交大计算机考研成绩,北京交通大学考研分数线_2021考研国家分数线什么时候出来...
  10. 使用kaggle跑李宏毅机器学习作业