一, 使用 CSS 滤镜和混合模式在线 PS
使用 CSS 滤镜和混合模式可以实现各种各样的图像处理效果, 内置众多图像处理效果, 部分效果示意如下缩略图:
进入 demo 页面你也可以点击这里的按钮, 更换你本地的素材, 查看对应的图像效果:
呈现的效果虽好, 但是也带来另外一个问题, 虽然视觉上是已经处理后的图片, 但是如果我们右键 - 图片另存为, 会发现还是原图.
如果用户觉得某个图片处理后的效果很棒, 想要保存到自己的本机, 就会受阻.
或者说, 我们基于 CSS 滤镜和混合模式制作了一款图像处理的工具, 最后需要把这些已经处理好的图片上传到后台, 作为一个独立的 < img > 元素使用, 也会受阻.
怎么办? 难道我们要放弃这么好的特性, 还使用 canvas 来处理图像吗?[图片上传失败...(image-9fb53e-1558444076034)]
不需要的, 实际上是有方法可以得到 CSS 处理后的图像的.
二, SVG foreignObject 元素与视觉存储
SVG 中有个 < foreignObject > 元素, 可以实现在 SVG 内部嵌入 Xhtml 元素, 例如:
- // canvas 转为 blob 并上传
- canvas.toBlob(function (blob) {
- // 图片 Ajax 上传
- var xhr = new XMLHttpRequest();
- // 文件上传成功
- xhr.onload = function() {
- // xhr.responseText 就是返回的数据
- };
- // 开始上传
- xhr.open("POST", 'upload.php', true);
- xhr.send(blob);
- }, 'image/jpeg');
而 SVG 本质上就是个图像, 也就是说, 我们只需要把图像处理相关的 HTML 代码和 CSS 代码放在 < foreignObject > 元素中, 然后作为 < img > 图像呈现, 然后再绘制到 canvas 画布上, 这样就可以得到纯正的处理后的位图图像了.
demo 页面最后一张图片和 CSS 处理后的图片长相虽同, 但是本质却不同, 一个还是原始图 (试试右键 - 另存为), 一个本质上是合成图 (试试右键 - 另存为), 如下截图示意:
于是, 接下来, 无论是是要下载到本机还是上传到服务器都不是问题.
关于上传, 可以传输图像 canvas.toDataURL() 的 base64 数据, 也可以传输 canvas.toBlob() 的 Blob 数据:
- // canvas 转为 blob 并上传
- canvas.toBlob(function (blob) {
- // 图片 Ajax 上传
- var xhr = new XMLHttpRequest();
- // 文件上传成功
- xhr.onload = function() {
- // xhr.responseText 就是返回的数据
- };
- // 开始上传
- xhr.open("POST", 'upload.php', true);
- xhr.send(blob);
- }, 'image/jpeg');
三, 我该如何在项目中使用?
上面的 demo 页面中, 我写了个名为 cssRenderImage2PureImage() 的方法, 可以把类似下面代码结构的 CSS 图像处理结果变成一张图片:
- <div id="input" class="clarendon-filter">
- <img src="./example.jpg">
- </div>
- .clarendon-filter {
- filter: contrast(1.2) saturate(1.35);
- display: inline-block;
- position: relative;
- }
- .clarendon-filter::before {
- content: '';
- display: block;
- height: 100%;
- width: 100%;
- top: 0; left: 0;
- position: absolute;
- background: rgba(127,187,227,.2);
- mix-blend-mode: overlay;
- pointer-events: none;
- }
cssRenderImage2PureImage() 方法语法:
cssRenderImage2PureImage(dom, callback);
其中:
dom
必须参数. DOM 对象.
callback
可选参数. Function. 回调方法, 支持一个参数, 为合成后的图片的 base64 信息.
示例:
- cssRenderImage2PureImage(input, function (url) {
- // url 就是合成后的图片 base64 地址
- // 你可以对 url 做你任何你想做的事情......
- });
四, 其它说明以及结束语
cssRenderImage2PureImage
方法高度定制, 如果你的 CSS 滤镜处理的 DOM 结构有所不同, 你需要根据你的项目场景调整下
cssRenderImage2PureImage
方法里面的代码;
<foreignObject > 元素是著名的 html2canvas 工具的核心, 通常一些小的局部的截图功能, 我们直接自己撸十几行代码处理下就好了, 更高效更灵活. 关于 SVG 的 < foreignObject > 元素, 我之前专门写过一个文章介绍过:"SVG <foreignObject > 简介与截图等应用", 想要深入了解实现原理的人可以看看.
此技术实现请在 Chrome 浏览器下玩耍.
本文所提供的解决方案和应用场景涉及到了 CSS 滤镜和混合模式, SVG <foreignObject > 元素, 以及 Canvas 的图像绘制和处理技巧. 幸好这 3 个领域是自己着重学习的领域, 如果有哪一方面缺失, 解决方案一定无法信手捏来.
我们究竟要学什么东西, 不是看这个东西到底热不热门, 而是要看跟你想感兴趣的领域是否相关, SVG 和 Canvas 实际上属于小众领域, 但都与图形表现密切相关, 因此, 义无反顾学习, 而且学习的时候不要只学热门的 API, 一些不常用的特性, API 也要面面俱到, 例如 SVG <foreignObject > 元素就是个很不常用的 SVG 元素, 但在这里大放异彩, 是技术实现的最关键部分.
自己是一个五年的前端工程师, 希望本文对你有帮助!
这里推荐一下我的前端学习交流扣 qun:731771211 , 里面都是学习前端的, 如果你想制作酷炫的网页, 想学习编程. 自己整理了一份 2019 最全面前端学习资料, 从最基础的 HTML+CSS+JS[炫酷特效, 游戏, 插件封装, 设计模式] 到移动端 HTML5 的项目实战的学习资料都有整理, 送给每一位前端小伙伴, 每天分享技术
点击: 加入
来源: http://www.jianshu.com/p/b843b165000d