canvas应用之前端实现为图片添加水印功能

819次阅读  |  发布于3年以前

前言

最近翻看面试题目,无意中发现了这个题目。所以自己就写一个demo。感觉很有趣,特分享出来。

实现思路

我们分析一下,什么叫图片添加水印?常见的添加水印都是在图片上面添加一个图层(内容:防伪标识或者是公司的logo之类)。

我们去淘宝找人设计的话,一般都是给添加了水印的图片。只要不给你原型图,基本上无法去除水印。

写到这里我们基本上可以判断,所谓的水印技术,就是两张图片。一张是我们的原图,另一种就是水印图片,然后水印图片就是那种透明背景的图片,这样两张图片叠加,既可以看见原图的内容,还加了标识。

方向确定了。现在我们需要考虑的就是如何让两张图片上下覆盖(请不要想着css实现,因为我们最终是要以图片的形式展示)。因为最后是要形成一张照片,所以就需要两张照片融合。

联想现实,我们如何让两个物体融合,固体肯定是无法直接融合。那么我们就需要将两块固体分别融化,然后按照规则,合并到一起。接着变回固体。

思路清晰了。

首先我们就是将两张图片,原图以及logo图片分别,变成二进制流(base64)。然后以canvas为画板,就像刷油漆一样,先画一层原图的样式,然后再将我们的logo覆盖上去。

实现:将图片变成二进制流

这个地方实现思路比较简单,主要是借助HTML5 的FileReader读取文件的信息,并将其转为base64。


/**
 * 将文件转换为base64
 * 这个函数我在 大文件上传那篇文章里也用过,感兴趣的同学可以去看看
 */
function fileParse (file, type) {
   const caseType = {
       'base64': 'readAsDataURL',
       'buffer': 'readAsArrayBuffer'
   }
   const fileRead = new FileReader()
   return new Promise(resolve => {
       fileRead[caseType[type]](file)
       fileRead.onload = (res) => {
       resolve(res.target.result)
       }
   }) 
}

### 实现:刷油漆式的在canvas上绘制两张图片

利用了canvas 的 drawImage方法。

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
img 规定要使用的图像、画布或视频。
sx 可选。开始剪切的 x 坐标位置。
sy 可选。开始剪切的 y 坐标位置。
swidth 可选。被剪切图像的宽度。
sheight 可选。被剪切图像的高度。
x 在画布上放置图像的 x 坐标位置。
Y 在画布上放置图像的 y 坐标位置。
width 可选。要使用的图像的宽度。(伸展或缩小图像)
height 可选。要使用的图像的高度。(伸展或缩小图像)

水印图片的形成,就是利用drawImage 方法在canvas上绘制就可以了。

总结

整体来讲思路比较简单,具体实现还是有些小细节。 需要注意的一点上,代码需要运行的服务下,建议使用http-serve。

同时,我的例子还有很多扩展的地方,比如我们可以移动我们的的水印的位置,这个在drawImage 中就可以配置。

当然这个例子有个鸡肋的地方,就是需要有一个水印图片。其实利用我们的所学知识就可以实现。我们正常中,可以将html生成图片下载,给用户一个输入框,输入水印文字,然后生成图片,再走上面的流程。文字大小,字体颜色,字体位置均可以。

这是我的一个实现思想,不一定对,但是确实可以尝试,明天争取实现这个功能,并分享出来。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8