近期项目需要做一个 定位打卡,拍照加上水印的功能,项目是用的react+Ant mobile
选用了 ImagePicker 图片选择器,代码如下
1 | <ImagePicker |
在onChange 里面调用方法,就能上传图片显示了,这里不多说介绍,上传图片的原理都差不多。
接下来说下给图片加水印的操作,在激烈的碰撞中,发现可以通过用Canvas,给图片上水印(本次是通过后台接口生成的),之后慢慢的预研了一波。
前端图片加水印原理很简单,主要分为下面几步:
- 将需要添加水印的图片绘制到 canvas 上
- 将水印图片绘制到 canvas 上
- 将 canvas 的内容导出为图片
前期学习
使用canvas在前端实现图片水印合成
1.在底图上加上想要的水印,核心代码如下
1 | 123456789101112// 获取当前 canvas 的上下文环境,用来操作在 canvas 上绘制内容const ctx = canvas.getContext('2d')// 向 canvas 上绘制图片// image 为一个图片对象// x 为绘制图片的横向起始位置,y 为绘制图片的纵向起始位置// width 为要绘制在 canvas 上宽度, height 为高度// 该方法最多可接受 9 个参数,从而实现剪裁的效果,但是与本篇内容无关,感兴趣的小伙伴可以搜索该方法ctx.drawImage(image, x, y, width, height)// 将 canvas 上的内容导出为 base64 格式的字符串,导出后可以直接赋值给 Image 对象的 src 属性// 第一个参数为导出的图片格式,可接受第二个参数(小于或等于 1 的数,表示导出图片的压缩比率)canvas.toDataURL("image/png")context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); |
drawImage接受参数示意
参数 | 描述 |
---|---|
img | 用来被绘制的图像、画布或视频 |
sx | 可选。img被绘制区域的起始左上x坐标。 |
sy | 可选。img被绘制区域的起始左上y坐标。 |
swidth | 可选。img被绘制区域的宽度(如果没有后面的width或height参数,则可以伸展或缩小图像)。 |
sheight | 可选。img被绘制区域的高度(如果没有后面的width或height参数,则可以伸展或缩小图像)。 |
x | 画布上放置img的起始x坐标。 |
y | 画布上放置img的起始y坐标。 |
width | 可选。画布上放置img提供的宽度(可能会有图片剪裁效果)。 |
height | 可选。画布上放置img提供的高度(可能会有图片剪裁效果)。 |
步骤
1、本地图片转成Base64
在onChange 上传图片 直接获取到的对象包含了base64格式的图片数据,如图:
2、使用H5 FlieReader
读取base64格式的图片数据,将图片数据赋值给image 对象
1 | const reader = new FileReader(); |
3、调用canvas元素画布上下文对象的drawImage方法即可实现将img内容绘制到画布
1 | const canvas = document.createElement('canvas'); |
drawImage这个方法可以传入多个参数(楼上已经述说过了),以定义绘制的图像的范围,这里传入的0, 0定义从图像左上角开始绘制,后面可以继续传入两个参数来定义图像的绘制终点,不过这里整个图片都要绘制到canvas,所以采用默认值即可。注意点:要设置画布的高宽,到时候图片需要平铺到整个画布上,不加 的话 大图会被裁剪掉。
4、在画布上添加水印并借助canvas的toDataURL()
方法把我们的canvas画布转换成base64无损PNG地址,这里就可以按照canvas的Api进行水印的操作
1 | // 设置填充字号和字体,样式 |
5、Demo完整代码如下:
1 | const reader = new FileReader(); |
这样就完整地给图片添加了水印效果,下面看一下实际效果,最终结果:
总结
前端给一个图片做简单的水印,canvas提供的一些API其实很有用,前端利用canvas的drawImage()可以实现对图片进行压缩,不妨大家可以试试,既然已经看到了最后,就请你伸出有魔力的手指点个关注吧!谢谢啦