第一种(较复杂)

根据图片路径获取图片数据,转成blob类型

用FileReader读取图片blob数据为dataURL

创建img标签,src属性为dataURL

监听img.onload, 创建canvas,将img对象draw在canvas里

添加水印

使用canvas.toBlob转成最终图像

代码

async/await版

/**

*

* @param {图片路径} imgUrl

* @param {图片宽度} width

* @param {图片高度} height

* @param {水印文字} watermarkText

*/

async function watermark(

imgUrl,

width = 300,

height = 300,

watermarkText = "zpfei.ink"

) {

// 1. 根据图片路径获取图片数据,转成blob类型

const fileBlob = await fetch(imgUrl)

.then((r) => r.blob())

.then((file) => file);

// 2. 用`FileReader`读取图片blob数据为dataURL

const reader = new FileReader();

reader.readAsDataURL(fileBlob);

// 3. 创建img标签,src属性为dataURL

const tempImg = await new Promise((resolve) => {

reader.onload = () => {

const img = document.createElement("img");

img.src = reader.result;

resolve(img);

};

});

// 4. 监听`img.onload`, 创建canvas,将img对象`draw`在canvas里

const canvas = await new Promise((resolve) => {

const canvas = document.createElement("canvas");

canvas.width = width;

canvas.height = height;

tempImg.onload = () => {

const ctx = canvas.getContext("2d");

ctx.drawImage(tempImg, 0, 0);

// 5. 添加水印

ctx.fillStyle = "red";

ctx.textBaseline = "middle";

ctx.fillText(watermarkText, 20, 20);

resolve(canvas);

};

});

// 6. 使用`canvas.toBlob`转成最终图像

const newImg = await new Promise((resolve) => {

canvas.toBlob((canvasBlob) => {

const newImg = document.createElement("img"),

url = URL.createObjectURL(canvasBlob);

newImg.onload = function () {

// 图片加载完成后销毁objectUrl

URL.revokeObjectURL(url);

};

newImg.src = url;

resolve(newImg);

});

});

// document.body.appendChild(newImg);

return newImg;

}

常规回调版

const imgUrl =

"https://cdn.jsdelivr.net/gh/zhangpanfei/static@demo/img/test.jpg";

fetch(imgUrl)

.then((r) => r.blob())

.then((file) => {

const reader = new FileReader();

reader.readAsDataURL(file);

reader.onload = () => {

const canvas = document.createElement("canvas");

canvas.width = 400;

canvas.height = 400;

const img = document.createElement("img");

img.src = reader.result;

img.onload = () => {

const ctx = canvas.getContext("2d");

ctx.drawImage(img, 0, 0);

ctx.fillStyle = "red";

ctx.textBaseline = "middle";

ctx.fillText("zpfei.ink", 20, 20);

canvas.toBlob((canvasBlob) => {

const newImg = document.createElement("img"),

url = URL.createObjectURL(canvasBlob);

newImg.onload = function () {

// 图片加载完成后销毁objectUrl

URL.revokeObjectURL(url);

};

newImg.src = url;

document.body.appendChild(newImg);

});

};

};

});

第二种(简单)

图片路径转成canvas

canvas添加水印

canvas转成img

代码

/**

* 图片路径转成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;

}

/**

* canvas添加水印

* @param {canvas对象} canvas

* @param {水印文字} text

*/

function addWatermark(canvas, text) {

const ctx = canvas.getContext("2d");

ctx.fillStyle = "red";

ctx.textBaseline = "middle";

ctx.fillText(text, 20, 20);

return canvas;

}

/**

* canvas转成img

* @param {canvas对象} canvas

*/

function convasToImg(canvas) {

// 新建Image对象,可以理解为DOM

var image = new Image();

// canvas.toDataURL 返回的是一串Base64编码的URL

// 指定格式 PNG

image.src = canvas.toDataURL("image/png");

return image;

}

// 运行示例

async function run() {

const imgUrl =

"https://cdn.jsdelivr.net/gh/zhangpanfei/static@demo/img/test.jpg";

// 1.图片路径转成canvas

const tempCanvas = await imgToCanvas(imgUrl);

// 2.canvas添加水印

const canvas = addWatermark(tempCanvas, "zpfei.ink");

// 3.canvas转成img

const img = convasToImg(canvas);

// 查看效果

document.body.appendChild(img);

}

html 图片加水印,js给图片加水印的两种方法相关推荐

  1. html+input改变图标,JS Input里添加小图标的两种方法

    我们在做网页的时候,经常需要在input里面添加小图标,那么这里就介绍比较常见的两种方法. 将小图标当做input的背景来插入,直接上代码吧: Box{ height: 50px; backgroun ...

  2. js获取classname值_利用js获取元素class值的两种方法

    我们有时为了达到某种效果,需要以元素的class值为条件做判断. 我们如何利用JavaScript获取元素class的值?我们先看下面代码: x=document.getElementsByTagNa ...

  3. JS实现千位分隔符的两种方法

    分享JS实现千位分隔符的两种方法 自己最好在 VScode 进行练习,看不如动手来得深刻 方法一:普通方法 <script>function numFormat(num) {var tmp ...

  4. html密码框怎么添加小图标,JS Input里添加小图标的两种方法

    我们在做网页的时候,经常需要在input里面添加小图标,那么这里就介绍比较常见的两种方法. 方法一 将小图标当做input的背景来插入,直接上代码吧: *{ margin: 0; padding: 0 ...

  5. JS实现合并单元格的两种方法

    本后端菜狗想在网上找合并单元格的代码,结果找到的都是太老的代码,然后就只能用Js手写了两种方法(第二种方法叫了个前端大佬写的) 废话不多说,直接上代码: (由于时间有点小久,就不写思路和过程啦) 第一 ...

  6. 使用js提交form表单的两种方法

    提交form表单的时候瑶族一些简单的验证,验证完后才能提交,避免无效提交. 1.当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在前端页面写:有两种方法,一种是用sub ...

  7. js提交form表单的两种方法

    当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在前端页面写:有两种方法,一种是用submit提交.一种是用button提交. 方法一: 在jsp的前端页面的头部插入一 ...

  8. html表单调用js方法,使用js提交form表单的两种方法

    提交form表单的时候瑶族一些简单的验证,验证完后才能提交,避免无效提交. 1.当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在前端页面写:有两种方法,一种是用sub ...

  9. php数字加零,php实现数字补零的两种方法

    本篇文章给大家带来的内容是关于php实现数字补零的两种方法 ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在php中有两个函数--至少有两个是否有其他的我还不知道,能够实现数字补零 ...

  10. python如何在图片上添加文字_Python在图片中添加文字的两种方法

    本文主要介绍的是利用Python在图片中添加文字的两种方法,下面分享处理供大家参考学习,下来要看看吧 一.使用OpenCV 在图片中添加文字看上去很简单,但是如果是利用OpenCV来做却很麻烦.Ope ...

最新文章

  1. 学python对学c++有帮助吗_2020,你该学习Python还是C++
  2. 【FPGA】SRIO IP核系统总览以及端口介绍(二)(I/O Port 含义介绍)
  3. python的源代码文件的扩展名是-python源文件后缀是什么
  4. 修改apk连接服务器地址,如何修改apk连接服务器地址
  5. Python3-笔记-E-006-库-路径os.path
  6. Centos6.3下DRBD+HeartBeat+NFS配置笔记
  7. Taro+react开发(70):flex布局
  8. 项目管理(2):备战pmp
  9. c语言系统的通用数据结构,(转载)C语言实现通用数据结构的高效设计
  10. UOJ#450. 【集训队作业2018】复读机 排列组合 生成函数 单位根反演
  11. USB接口类型的区别
  12. DroidCam连接教程+资源
  13. 月入万元或不需缴税!九张图带你看懂个税新规
  14. zabbix报警方式,邮件报警和微信报警。
  15. 机器视觉的相机标定到底是什么?
  16. elasticsearch搭建与java应用实例
  17. 接口报错500是什么意思_网页打开显示错误500是什么意思
  18. Prometheus+Alertmanager详细配置邮箱告警
  19. iOS获取设备的唯一标识的方法总结以及最好的方法
  20. 视频文件用数据恢复软件恢复了,但是打开不,到底能不能修复好?

热门文章

  1. 目前最新《脑动力 html+css标签速查效率手册[刘丽霞] 》
  2. 【线性代数】矩阵的三种相乘方式
  3. Android LCM特殊分辨率时,360camera预览异常分析
  4. windows7 如何关闭开机启动讲述人
  5. 德国商标怎么注册?德国商标注册流程及费用
  6. Abb工业机器人,用函数测出两点间的距离
  7. 2017年阿里巴巴实习生招聘笔试
  8. 嘘!我有特殊的绕线画技巧,教你用MATLAB绘制另一种绕线画
  9. 哈工大计算机学院计算机组成原理,哈工大威海计算机学院计算机组成原理.ppt...
  10. gtav登录请确认不是机器人_请冷静:R星更新网站图片并不是在暗示GTA6