Web前端之高斯模糊图片记

题记 前端需求之高斯模糊图片

最近工作中有一个需求,客户提交图片,服务器根据图片生成内容,并将内容显示,要求高斯模糊处理用户的图片并作为作品展示的背景,类似于苹果设备上的高斯模糊背景。用户提交的图片分网络图片地址、终端设备上传两种。要求兼容各大浏览器。

解决方案一:CSS3滤镜

在CSS3 中规定了一个新的图形特效:filter ,可以对元素进行模糊、锐化或者元素变色。 filter 目的是用来调整图片、背景和边界的渲染。

在CSS3 中已经实现了filter 的一些预定义函数,MDN 中介绍如下:

filter: url("filters.svg#filter-id");
filter: blur(5px);
filter: brightness(0.4);
filter: contrast(200%);
filter: drop-shadow(16px 16px 20px blue);
filter: grayscale(50%);
filter: hue-rotate(90deg);
filter: invert(75%);
filter: opacity(25%);
filter: saturate(30%);
filter: sepia(60%);

/* Apply multiple filters */
filter: contrast(175%) brightness(3%);

/* Global values */
filter: inherit;
filter: initial;
filter: unset;

详见:MDN中对 filter 的介绍

其中blur() 正是对元素进行高斯模糊,顺便添加了brightness() 函数增加前景背景明暗对比度。

  -webkit-filter: blur(10px) brightness(.5); /* Chrome, Opera */
     -moz-filter: blur(10px) brightness(.5);
      -ms-filter: blur(10px) brightness(.5);
          filter: blur(10px) brightness(.5);
background-image: url(/*用户图片地址*/);

在谷歌浏览器、火狐浏览器、Edge 浏览器中展示,效果不错,但是在IE 中不行。

CSS3 filter 的浏览器兼容列表如下:

IE的CSS filter

IE 没有实现CSS3 的filter ,因为它们本来就有自己的filter 滤镜实现。IE 中的filter 实现了和CSS3 中 filter 类似的方法,但是filter 方法的调用却与CSS3 中的filter 方法大相径庭。Microsoft 早在 IE 4.0 中就开始了filter 的支持,很明显CSS3 中的filter 借鉴了IE 的思想却用了比IE 更切合的方式实现了这些方法,为IE 点赞。关于IE 中的CSS-filter 的知识详见关于IE中CSS-filter滤镜小知识介绍。于是添加上IE 中的高斯模糊实现:

filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius=10, MakeShadow=false); /* IE6~IE9 */

到这里发现并没有万事大吉,大家会发现IE filter 代码中的注释是IE6~IE9。IE10、IE11是不支持CSS 中 filter 的语法的,想来可能是Microsoft 想在IE 10 后支持CSS3 中的filter 却发现与之前的实现有冲突,然后不得不舍弃,最终也没拿出方案吧。所以只得寻找新的方案。

解决方案二:HTML5 之 canvas

canvas 中有一个getImageData() 方法,可以获取图片上的像素点信息,还有一个方法putImageData() 可以将图像的像素点信息修改后写入到canvas 上,canvas 也提供了方法toDataURL() 将图像信息导出成路径供其它用处(譬如作为其他元素的背景),将canvas 画图作为其他元素的背景可查看使用canvas 绘制背景图-Jerry Qu 的介绍。我们获取图片的信息后对图片信息进行转化后写回canvas ,就能得到想要的效果。当然,使用不同的算法会得到不同的结果,canvas 生成马赛克图片 介绍了不同的图片处理插件,有兴趣的可以在上面详细了解。我们要使用的是高斯模糊的插件,对高斯模糊算法,阮老师的一篇译文——高斯模糊算法 介绍的很不错,主要涉及正态分布。不过我们现成的实现,在网上找到这个JS插件——StackBlur.js,Demo地址:http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html

该插件可以实现高斯模糊效果,主要使用里面的方法

function stackBlurImage( imageID, canvasID, radius, blurAlphaChannel )

其中, imageID 是html 页面中要高斯模糊的原图片标签ID,canvasID 是canvas 画图的ID,radius 是要高斯模糊的半径,blurAlphaChannel 涉及半透明(未详细研究)。

于是敲定解决方案:在html 页面中插入隐藏标签<img />和隐藏的标签<canvas></canvas>,使用插件中方法设置作品展示的背景。方案敲定开始编码,写完后上传了一张图片,服务器保存后将图片地址保存后返回图片地址,前端处理。测试,通过,完美兼容各大浏览器。

问题出现在项目改造,使用独立的图片服务器后,图片服务器和Web 服务器在不同的域下,所以在运行 stackBlurImage() 是浏览器报出了如下错误:

Uncaught SecurityError: Failed to execute ‘getImageData‘ on ‘CanvasRenderingContext2D‘: The canvas has been tainted by cross-origin data.

造成这个问题的原因是图片跨域,在canvas 修改图片信息的时候,像其他数据一样,图片信息的访问也有域的限制,跨域图片的详细介绍可参见MDN 上的讲解:CORS enable image  。跨域限制是html 规范上要求的,各个浏览器是否实现虽有差别,但至少Chrome 上是不行的(存在其他浏览器并未对canvas 中的这一点做限制),看到一些博客介绍修改浏览器设置也可以突破这个限制,但显然这不是产品级的解决方案。

存在这个问题的不仅仅是因为文件服务器独立出来,如果用户提交的是第三方网站的图片地址,一样存在这个问题,只是当时未发现而已。于是考虑使用JS 将图片下载到本地再使用,可是JS 也有跨域的限制,仍然不可行。

尝试解决方案三:CSS3 之 transform

CSS3 提供了很多变换,其中 transform 就可以对元素进行旋转(rotate)、位移(translate)、缩放(scale)、倾斜(skew)等2D3D转换(MDN讲解:transform),当然,这些转换斗是以 matrix(矩阵) 为基础方法在坐标系统中对可视化模型的坐标空间进行操作。既然如此,若有合适的矩阵是否能达到元素“高斯模糊的效果”呢?于是对 matrix(矩阵) 进行探究。

matrix(矩阵) 主要原理是对元素点集合的各个点坐标进行线性代数转换,以达到元素变形的目的。CSS3 transform 的2D转换 matrix() 方法写法如下:

transform: matrix(a,b,c,d,e,f);

这六个参数对应的矩阵就是:

坐标转换的过程如下:

3*3矩阵每一行的第1个值与后面1*3的第1个值相乘,第2个值与第2个相乘,第3个与第3个,然后相加。2D转换使用了3*3矩阵,3D 转换多了一个Z轴,使用的是4*4矩阵。两种转换的本质是一样的,只是复杂度不同。上面这一段介绍来自张旭鑫的博客,理解CSS3 transform中的Matrix(矩阵) 。他的另一篇博客对 3D 转换进行了详细而又个性的介绍,好吧,CSS3 3D transform变换,不过如此 。感谢大神们的分享。

也就是说 transform 转换的实质是对坐标点的变化,并不能对图片的像素点数据进行操作,能进行各种变形,却改变不了元素的本质,高斯模糊改变了图片的像素点,transform 并不能解决我们的问题。

解决方案四:SVG高斯模糊

SVG 是用XML格式定义在Web 平台上的矢量图,它是一个开放标准,它将图像信息以XML 文本形式进行保存和传输,SVG 里也提供了滤镜来该表元素的显示,其中包括高斯模糊。我们先来看看SVG 的浏览器兼容性:

回顾我们使用的过的解决办法,方案二有同源策略的限制,方案三不可用,方案一兼容了除IE10+外的主流浏览器,如果我们使用SVG滤镜将IE10+ 的坑填上,便得到一个完美的解决方案。根据 SVG 的教程 中的介绍,SVG 滤镜主要使用了<defs> 和<filter> 标记。保存一个名为 blur.svg 的SVG 文件,文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:ev="http://www.w3.org/2001/xml-events"
     baseProfile="full">
     <defs>
        <filter id="blur">
            <feGaussianBlur stdDeviation="10" />
        </filter>
    </defs>
    <image xlink:href="mm1.jpg" x="0" y="0" height="191" width="265" filter="url(#blur)" />
</svg>
红色部位的代码便提供了一个高斯模糊滤镜(模糊半径为10),<image> 标记提供了要模糊的图片,属性 xlink:href 是图片的地址,属性 filter 根据ID 应用了红色代码定义的滤镜,然后SVG 作为背景图片载入:

.blur {
    background-image: url(blur.svg);
}

这样就达到了我们的目的——高斯模糊图片,但仍然存在一个问题,以上的SVG 文件单独于html 页面,需要额外的维护,要命的是图片的地址很难改变,于是我们把以上 SVG 标签的内容作为内联元素放在了 html 页面中,并和作品展示的容器同级。然后将他们的父元素 position 设为 relative ,作品容器背景色设为透明。对 <svg> 标签应用以下样式作为作品容器的背景,


width: 120%;
height: 120%;
position:absolute;
top:-10%;
left:-10%;

最后是使用 JS 调节 <svg> 标签中的 <iamge> 宽高属性以完美展示。

至此,问题得以解决。

时间: 2024-10-12 10:50:26

Web前端之高斯模糊图片记的相关文章

值得收藏的Web前端精美相册图片展示(下)

4. jquery图片相册插件 能在支持 FireFox.Chrome.Safari.傲游.搜狗.360浏览器. 源码下载/   在线演示 5.  js向上推送幻灯片 源码下载  /  在线演示 6.  jQuery画廊插件 源码下载 /  在线演示 7. jquery图片闪光幻灯片 源码下载/   在线演示 值得收藏的Web前端精美相册图片展示(下)

10款web前端动感的图片动画效果

1.Salvattore:CSS 驱动的 jQuery Masonry 插件 Salvattore 是一个 jQuery 砌体的替代,使用 CSS 驱动的配置.Salvattore 根据您指定的列数组织你的 HTML 元素.容器中的每一个项目会一个接一个被放置在列内,只需要简单地添加一个 data-columns 属性.在你的 CSS 文件中,你可以设置你想为元素创建的列数.要创建一个具有响应性的柱状设计,只需使用媒体查询.项目附加在同一容器的前面,不会发生冲突.您可以结合 XHR 功能的 AP

web前端性能优化-图片优化实战分享

说在开头 项目做完顺利上线了.上线之前的2天做了一点性能上的优化.由于我们这个项目最主要的就是图片.所以,就准备对自己负责的模块的图片和图标进行适当的优化.因为以前看过雅虎军规.所以主要从减少请求数量,图片压缩,以及cssSprite对图片进行一些处理. 重点 请求数量 由于项目开发的时候为了赶进度,所以的icon和图片都是单独一个一个的:看了一些自己负责的会员中心登录和搜索,居然图片有240多张:这就意味着要请求200多次才能加载完所有的图片. 比较突出的就是会员中心首页,大概有图片20几个,

web前端图片极限优化策略

随着web的发展,网站资源的流量也变得越来越大.据统计,60%的网站流量均来自网站图片,可见对图片合理优化可以大幅影响网站流量,减小带宽消耗和服务器压力. 一.现有web图片格式 我们先来看下现在常用的web图片的格式: 图片格式 支持透明 动画支持 压缩方式 浏览器支持 相对原图大小 适应场景 baseline-jpeg 不支持 不支持 有损 所有 由画质决定 所有通用场景 progressive-jpeg 不支持 不支持 有损 所有 由画质决定 所有通用场景, 渐进式加载 gif 支持 支持

WEB前端开发中的图片压缩

web前端开发中,图片的重要性不言而喻,而由于一些图片的大小加上现在国内的网速不给力等种种原因,我们非常有必要对网站使用的图片进行压缩,压缩图片必然会带来图片质量的损失,我们要尽可能的在质量降低很小的情况下压缩图片,以便让网站更快的加载,提高用户体验度. 我在工作中,压缩图片用到了三个方法,分享给大家: 一.使用windows自带的画图工具 1.使用画图工具打开想要压缩的图片:2.什么都不用做,直接另存为你想要的图片格式,你会发现它比源文件小了很多,而且质量看不出来损失. 这个方法简单,快捷,压

WEB前端:05_scroll滚动(图片/文字滚动)

scroll滚动(图片/文字滚动) 网站常用效果之一,以下为简化版,用于学习javascript基础知识. 效果图: scroll滚动(图片/文字滚动)- 纯JS简化版 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 5

记一次web前端开发的电话面试

前几天经历了一次电话面试,因为我是应届生,题目难度不大,只是考察个人的基础知识的掌握程度.都怪我没有及时记下来~~题目不是很全.下面是我记得的,请看题. 问:png与jpg的区别是什么? 问:png8与png24的区别是什么?png的交错与不交错分别是什么意思? 问:闭包是什么?举个例子说明? 问:匿名函数是什么?举个例子说说它的用法? 问:根据什么知道页面内容是缓存着的? 问:浏览器的状态码的问题,302是什么意思? 问:无缝滚动用jquery的时候是用什么方法实现? 问:javascript

web前端入门到实战:背景关联和缩写以及插图图片和背景图片的区别

一.背景属性缩写的格式 1.backgound:背景颜色 背景图片 平铺方式 关联方式 定位方式 2.注意点: 这里的所有值都可以省略,但是至少需要一个 3.什么是背景关联方式 默认情况下,背景图片会随着滚动条的滚动而滚动,如果不想这样,那么我们可以修改它们的关联方式 4.格式: background-attachment:值: 值的取值范围: scroll:默认值,会随着滚动条而滚动. fixed:不会随着滚动条滚动而滚动. 5.例子: <!DOCTYPE html> <html la

web前端入门到实战:详解css3如何给背景图片加颜色遮罩

前段时间在开发中,遇到需要给背景层加颜色遮罩的项目,现在特定总结一下给背景图层加颜色遮罩的方法. 方法一:通过定位叠加(注意层级) <div class="wrap1"> <div class="inner"> </div> </div> .wrap1 { position: relative; width: 1200px; height: 400px; background: rgba(0, 0, 0, .5); }