这篇文章发布于 2019年04月20日,星期六,23:30,归类于 JS实例。 阅读 21056 次, 今日 1 次 8 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8598
本文可全文转载,个人网站无需授权,但需要保留原作者、出处以及文中链接,任何网站均可摘要聚合,商用请联系授权。
一、使用CSS滤镜和混合模式在线PS
使用CSS滤镜和混合模式可以实现各种各样的图像处理效果,例如CSSgram项目,内置众多图像处理效果,部分效果示意如下缩略图:
您可以狠狠地点击这里:CSSgram中的图像处理demo
进入demo页面你也可以点击这里的按钮,更换你本地的素材,查看对应的图像效果:
呈现的效果虽好,但是也带来另外一个问题,虽然视觉上是已经处理后的图片,但是如果我们右键-图片另存为,会发现还是原图。
如果用户觉得某个图片处理后的效果很棒,想要保存到自己的本机,就会受阻。
或者说,我们基于CSS滤镜和混合模式制作了一款图像处理的工具,最后需要把这些已经处理好的图片上传到后台,作为一个独立的<img>
元素使用,也会受阻。
怎么办?难道我们要放弃这么好的特性,还使用canvas来处理图像吗?
不需要的,实际上是有方法可以得到CSS处理后的图像的。
二、SVG foreignObject元素与视觉存储
SVG中有个<foreignObject>元素,可以实现在SVG内部嵌入XHTML元素,例如:
<svg xmlns="http://www.w3.org/2000/svg"> <foreignObject width="120" height="50"> <body xmlns="http://www.w3.org/1999/xhtml"> <p>文字。</p> </body> </foreignObject> </svg>
而SVG本质上就是个图像,也就是说,我们只需要把图像处理相关的HTML代码和CSS代码放在<foreignObject>
元素中,然后作为<img>
图像呈现,然后再绘制到canvas画布上,这样就可以得到纯正的处理后的位图图像了。
眼见为实,您可以狠狠地点击这里:SVG foreignObject存储CSS滤镜和混合模式处理的图片demo
demo页面最后一张图片和CSS处理后的图片长相虽同,但是本质却不同,一个还是原始图(试试右键-另存为),一个本质上是合成图(试试右键-另存为),如下截图示意:
于是,接下来,无论是是要下载到本机还是上传到服务器都不是问题。
关于纯前端下载图片,可以参考我之前这篇文章:“JS前端创建html或json文件并下载”的part3部分。
关于上传,可以传输图像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元素,但在这里大放异彩,是技术实现的最关键部分。
好了,点到为止。
总之,希望本文能够可以解决你的项目需求。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=8598
(本篇完)
- 小tips:使用canvas在前端实现图片水印合成 (0.571)
- SVG <foreignObject>简介与截图等应用 (0.534)
- 借助ffmpeg.wasm纯前端实现多音频和视频的合成 (0.387)
- 纯CSS图片滤镜项目CSSgram简介 (0.319)
- 做了个纯前端JPG/PNG尺寸缩放+压缩的在线工具 (0.293)
- canvas文本绘制自动换行、字间距、竖排等实现 (0.240)
- 图片动态局部毛玻璃模糊效果的实现 (0.220)
- 瞎折腾:把JS,CSS任意文本文件加密成一张图片 (0.204)
- JS检测PNG图片是否有透明背景、抠图等相关处理 (0.183)
- JS前端创建html或json文件并浏览器导出下载 (0.130)
- 不使用font-weight等CSS实现文字变瘦或变胖效果 (RANDOM - 0.031)
鑫旭大佬,我用了这个方法转换图片,产生了svg里面的图片无法显示的问题,不知道是不是svg本身的一些原因呢?最近看到了另外一种办法是将CSS滤镜转换成Canvas滤镜,然后用Canvas的另存图片功能,这种方法是不是更稳定呢?
看不懂咋办
文章不错,可否申请友链,我网站也是个人原创博客,与贵网站类似。希望可以交换友链
新技能get
很棒~
下载下来的图片后缀为什么是jfif
你用的什么浏览器?应该不至于
学习了,谢谢