JS前端基于canvas给图片添加水印

前两天给个人网站添加了一个小功能,就是在文章编辑上传图片的时候自动给图片加上水印。给网页图片添加水印是个常见的功能,也是互联网内容作者保护自己版权的方法之一。本文简单记录一下借助canvas在前端实现图片添加水印的实现方法。
canvas元素其实就是一个画布,我们可以很方便地绘制一些文字、线条、图形等,它也可以将一个img标签里渲染的图片画在画布上。

在上传文件到后端的时候,使用input标签读取用户本地文件后得到的其实是一个Blob对象(更精确的说是File对象,特殊的Blob对象);而在页面上展示一个图片使用的是img标签;绘制功能用canvas实现。添加水印的功能需要在img标签、canvas画布、Blob对象这三者之间相互转换,通过一些API可以完成这个工作:

我们可以从本地读取图片Blob,然后渲染到img标签,使用canvas绘制img内容并且绘制水印内容到画布,再将canvas内容转为Blob对象上传服务器,这样就完整实现了图片+水印的功能。

一、本地读取图像文件渲染到img标签

本地读取图片文件将会得到一个Blob对象,我们可以借助FileReader.readAsDataURL方法读取Blob的内容,并得到一个Base64编码的文件内容,可以将该内容赋值给img.src从而在浏览器上渲染出本地的图像。当然,img并非必须渲染到DOM树。读取操作是个异步操作,读取完成会触发load事件,为了便于之后的调用,我们可以用一个Promise包装这个操作,最后返回一个Promise对象。

function blobToImg (blob) {
 return new Promise((resolve, reject) => {
  let reader = new FileReader()
  reader.addEventListener('load', () => {
   let img = new Image()
   img.src = reader.result
   img.addEventListener('load', () => resolve(img))
  })
  reader.readAsDataURL(blob)
 })
}

二、将img标签内容绘制到canvas画布

调用canvas元素画布上下文对象的drawImage方法即可实现将img内容绘制到画布。

function imgToCanvas (img) {
 let canvas = document.createElement('canvas')
 canvas.width = img.width
 canvas.height = img.height
 let ctx = canvas.getContext('2d')
 ctx.drawImage(img, 0, 0)
 return canvas
}

drawImage这个方法可以传入多个参数,以定义绘制的图像的范围,这里传入的0, 0定义从图像左上角开始绘制,后面可以继续传入两个参数来定义图像的绘制终点,不过这里整个图片都要绘制到canvas,所以采用默认值即可。

三、canvas画布上绘制水印并转换为Blob对象

在图片上传的时候,我们通常采用FormData,图片文件以一个Blob对象的形式放到FormData中,所以我们需要把canvas再转为Blob以便文件上传等操作。利用HTMLCanvasElement.toBlob方法:

function watermark (canvas, text) {
 return new Promise((resolve, reject) => {
  let ctx = canvas.getContext('2d')
  // 设置填充字号和字体,样式
  ctx.font = "24px 宋体"
  ctx.fillStyle = "#FFC82C"
  // 设置右对齐
  ctx.textAlign = 'right'
  // 在指定位置绘制文字,这里指定距离右下角20坐标的地方
  ctx.fillText(text, canvas.width - 20, canvas.height - 20)
  canvas.toBlob(blob => resolve(blob))
 })
}

四、图片添加水印完整接口

将以上三个步骤结合起来,就完整地实现了从图片添加水印,下面是一个简单的使用示例:从本地选择一个图片文件,然后添加水印后,在传入的dom元素下预览添加水印后的图片。

function imgWatermark (dom, text) {
 let input = document.createElement('input')
 input.setAttribute('type', 'file')
 input.setAttribute('accept', 'image/*')
 input.onchange = async () => {
  let img = await blobToImg(input.files[0])
  let canvas = imgToCanvas(img)
  let blob = await watermark(canvas, text)
  // 此处将Blob读取到img标签,并在dom内渲染出来;如果是上传文件,可以将blob添加到FormData中
  let newImage = await blobToImg(blob)
  dom.appendChild(newImage)
 }
 input.click()
}

给页面加一个id为container的div元素,然后如下调用:

let dom = document.querySelector('#container')
imgWatermark(dom, '水印文字')

这样就完整地给图片添加了水印效果,下面看一下实际效果,你也可以在线体验。

添加水印前:

添加水印后(水印内容:“腾冲·清凉山”):

五、总结

本文仅仅介绍了图像+水印文字的简单实现,但是涉及的一些接口其实很有用。比如有时候遇到的一个功能是头像上传的预览和剪裁,这时候你可以利用FileReader来读取文件内容预览,利用CanvasRenderingContext2D.drawImage来实现剪裁功能。关于本文涉及接口的更多详细用法,可以参照MDN文档,文章中的API都使用了链接的形式链接到了MDN。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 利用js canvas实现五子棋游戏

    本文实例为大家分享了canvas实现五子棋游戏的具体代码,供大家参考,具体内容如下 html部分 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> &l

  • js canvas实现俄罗斯方块

    本文实例为大家分享了canvas实现俄罗斯方块的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title

  • js通过canvas生成图片缩略图(canvas)

    现今大部分的网络应用在上传图片的时候都会同时保存几种尺寸的图片,专业术语也就是生成缩略图,而对于生成缩略图一般做法是通过后端语言php等来生成,但是为了给服务器减压,我们或许可以从前端来着手,先生成好不同尺寸的缩略图,传给后端,而后端只需要将前端传过来的图片进行存储就好了. 使用Canvas我们可以轻松生成各种尺寸的图片,具体实现如下: function resizeImage(src,callback,w,h){ var canvas = document.createElement("can

  • js+canvas实现转盘效果(两个版本)

    本文实例为大家分享了js+canvas实现转盘效果的具体代码,供大家参考,具体内容如下 用到了canvas的绘制,旋转,重绘操作,定时器,文本,平移,线条,圆,清理画布等等: 版本一 不可以点击,刷新旋转 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>转盘抽奖</title> <style type="text/css&quo

  • js+canvas实现画板功能

    本文实例为大家分享了js+canvas实现画板功能的具体代码,供大家参考,具体内容如下 1.实现了画图,改变画笔粗细,改变画笔颜色,清屏功能 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>画板</title> <link rel="shortcut icon" type="image/x-icon&qu

  • js+h5 canvas实现图片验证码

    本文实例为大家分享了js+h5 canvas实现图片验证码的具体代码,供大家参考,具体内容如下 实现效果 一.使用技术 原生js技术+html5 canvas画图 利用Math.random()函数随机生成 颜色 字符串  及障碍物 点击 验证码可变更验证码图案 二.使用步骤 1.html+css 代码如下(示例): <div class="login_code_box"> <div class="login_code"> <input

  • JS页面动态绘图工具SVG,Canvas,VML介简介

    说到绘图.报表之类的技术,大家首先想到的就是Flex,当然也有许多了解javaapplet,对于这两种技术来说,各有利弊. 首先Flex很笨重,但是其效果实在让人喜欢.对于javaapplet来说,至少我在网络上很少看到,当然对于我们做开发的来说在我们的开发工具或者内部网络上还是有一些的. 其实现在Web上进行绘图的话还是有很多选择的,你可以到谷歌上搜索JS绘图,会有很多绘图工具提供给你使用,而且功能非常强大.比如说maxGraph,你可以到http://www.jgraph.com/mxgra

  • 微信小程序canvas动态时钟

    本文实例为大家分享了微信小程序canvas动态时钟的具体代码,供大家参考,具体内容如下 canvas时钟效果图: 代码: wxml: <view style='width:100%;height:{{canvasHeight}}px' catchtap='goCountdown'catchlongtap='touchstart' catchtouchend='touchend'> <canvas canvas-id='clock' style='width:100%;height:{{c

  • JS前端基于canvas给图片添加水印

    前两天给个人网站添加了一个小功能,就是在文章编辑上传图片的时候自动给图片加上水印.给网页图片添加水印是个常见的功能,也是互联网内容作者保护自己版权的方法之一.本文简单记录一下借助canvas在前端实现图片添加水印的实现方法. canvas元素其实就是一个画布,我们可以很方便地绘制一些文字.线条.图形等,它也可以将一个img标签里渲染的图片画在画布上. 在上传文件到后端的时候,使用input标签读取用户本地文件后得到的其实是一个Blob对象(更精确的说是File对象,特殊的Blob对象):而在页面

  • JS前端使用canvas编写一个签名板

    目录 需求 方案分析canvas 涉及知识点 代码 以上代码,未开发的点 需求 需求是做不完了,福利也被砍了,旅游也泡汤了,手上有2个需求,还没做完,PM就来新需求了. 开发一个签名板:要求PC端/移动端都能用.扫码签名.实时同步.可以改变笔画粗细.笔画颜色.可以生成base64图片. 方案分析canvas 1.获取页面[canvas]元素,设置宽高(800*200) 2.通过**HTMLCanvasElement.getContext()**  方法返回[canvas] 的上下文ctx 3.初

  • js前端实现多图图片上传预览的两个方法(推荐)

    一.将图片转成icon码的实现方式 html代码: <div class="yanzRight"> <input style="margin-top:5px;float: left;" id="st18" name="evidence" onchange="previewImage(this,5)" type="file"/> <span class=&qu

  • JS前端使用Canvas快速实现手势解锁特效

    目录 前言 Demo 需要实现的功能 初始化数据和页面渲染 touchstart 手指开始触摸事件 touchmove 监听手指滑动事件 touchend 监听手指触摸结束事件 页面滚动处理 连接的两颗星星之间有其他星星时 前言 之前在公司开发活动项目的时候,遇到一个项目需求要让用户使用手势画星位图来解锁星座运势,一看设计稿,这不就是我们平时的手机屏幕解锁吗?于是上网搜了一些关于手势解锁的文章,没找到可以直接复用的,于是只能自己打开canvas教程,边学习边设计实现了这个功能,同时兼容了移动端和

  • JS前端使用canvas动态绘制函数曲线示例详解

    目录 前言 第一步:绘制坐标系 1.如何确定 x 轴和 y 轴的边界值 2.不是传入多少网格数就是多少网格 3.如何让坐标原点位于画布中心 4.刻度总是会有浮点数 第二步:画函数曲线 第三步:绘制辅助线和交点坐标 第四步:平移 第五步:缩放 第六步:动态绘制曲线 第七步:模糊到高清 前言 不说废话,我们直入主题.先来看看读了这篇文章你将得到什么,就是下面这个东西啦(是不是很清晰很顺滑): 那具体要做什么呢,我们来简单拆解一下步骤: 绘制坐标系 绘制多条函数曲线 绘制辅助线和坐标点 支持平移.缩放

  • JS前端使用canvas实现扩展物体类和事件派发

    目录 前言 FabricImage 图片类 事件派发 小结 前言 虽然我们讲了这么多个章节,但其实目前为止就只有一个 Rect 类能用,略显单调.于是乎,为了让整个画布稍微生动一些,这个章节我们来尝试增加一个图片类,如果你以后需要扩展一个物体类,也是用同样的方法. 另外有时候我们还希望在物体属性改变时或者画布创建后做一些额外的事情,这个时候事件系统就派上用场啦,也就是我们常说的发布订阅,我觉的这是前端应用最广的设计模式没有之一了

  • JS前端绘图canvas模糊问题示例高清图解

    目录 缘起 模糊的原因 1.canvas 的大小和 css 的大小不一致 2.当绘制的东西不足 1px,会自动补足 1px 3.受到高清屏的影响 结语 缘起 模糊在 canvas 中应该算是个经典问题了,相信大家也曾经看过很多相关文章,但总是记不住,因为概念很多,描述的也不够明确,所以我就自己总结了一篇,刨去了复杂概念,顺带画了几张高清图,以此加深理解(我觉得画的贼好,记不住就来打我). 模糊的原因 总的来说模糊的原因大致可分为以下三点: 1.canvas 的大小和 css 的大小不一致 首先让

  • JS前端使用canvas实现物体的点选示例

    目录 前言 hover 的实现 click 的实现 矩形的坐标哪来的 点在多边形内的其他判断方法 穿透 本章小结 前言 上个章节中我们已经给物体加上了被选中的效果,现在可以上点交互了,这个章节主要实现的就是物体的 hover 和 click 事件,当鼠标 hover 到物体上时,我们会改变鼠标的样式使其变成移动的样子: 当 hover 到控制点时则会变成对应的操作样式: 当 click 物体时,会将物体变成激活态,也就是展示边框和控制点.话不多说,直接开撸 hover 的实现 首先我们来处理鼠标

  • JS前端可视化canvas动画原理及其推导实现

    目录 前言 动画的本质 动画的实现 动画的推导 小结 前言 到目前为止我们的 fabric.js 雏形已经有了,麻雀虽小五脏俱全,我们不仅能够在画布上自由的添加物体,同时还实现了点选和框选,并且能够对它们做一些变换,不过只有变换这个操作还不够灵活,要是能够让物体动起来就好了,于是就引入了这个章节的主题:动画,以及动画最核心的一个问题,如何保证在不同的电脑上达到同样的动画效果?然后说干就干,立马开撸. 虽然我写的是系列文章,但每个章节单独食用是木问题的,所以,请放心大胆的看

  • 使用JS前端技术实现静态图片局部流动效果

    目录 背景 效果 实现 HTML 页面结构 feTurbulence 和 feDisplacementMap CSS 样式 mask-image JavaScript 方法 ① 绘制热点图 ② 生成动画 ③ 清除画布 ④ 切换图片 总结 声明:本文涉及图文和模型素材仅用于个人学习.研究和欣赏,请勿二次修改.非法传播.转载.出版.商用.及进行其他获利行为. 背景 如果你有玩过 <王者荣耀>.<阴阳师> 等手游,一定注意到过它的启动动画.皮肤立绘卡片等场景,经常采用静态底图加局部液态流

随机推荐