wordpress两个站点共用用户,资源搜索器,上海建筑设计院有限公司停工,手绘教学网站题记 前端需求之高斯模糊图片最近工作中有一个需求#xff0c;客户提交图片#xff0c;服务器根据图片生成内容#xff0c;并将内容显示#xff0c;要求高斯模糊处理用户的图片并作为作品展示的背景#xff0c;类似于苹果设备上的高斯模糊背景。用户提交的图片分网络图片地…题记 前端需求之高斯模糊图片最近工作中有一个需求客户提交图片服务器根据图片生成内容并将内容显示要求高斯模糊处理用户的图片并作为作品展示的背景类似于苹果设备上的高斯模糊背景。用户提交的图片分网络图片地址、终端设备上传两种。要求兼容各大浏览器。解决方案一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;其中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 filterIE 没有实现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(PixelRadius10, MakeShadowfalse); /* IE6~IE9 */到这里发现并没有万事大吉大家会发现IE filter 代码中的注释是IE6~IE9。IE10、IE11是不支持CSS 中 filter 的语法的想来可能是Microsoft 想在IE 10 后支持CSS3 中的filter 却发现与之前的实现有冲突然后不得不舍弃最终也没拿出方案吧。所以只得寻找新的方案。解决方案二HTML5 之 canvascanvas 中有一个getImageData() 方法可以获取图片上的像素点信息还有一个方法putImageData() 可以将图像的像素点信息修改后写入到canvas 上canvas 也提供了方法toDataURL() 将图像信息导出成路径供其它用处(譬如作为其他元素的背景)将canvas 画图作为其他元素的背景可查看使用canvas 绘制背景图-Jerry Qu 的介绍。我们获取图片的信息后对图片信息进行转化后写回canvas 就能得到想要的效果。当然使用不同的算法会得到不同的结果canvas 生成马赛克图片 介绍了不同的图片处理插件有兴趣的可以在上面详细了解。我们要使用的是高斯模糊的插件对高斯模糊算法阮老师的一篇译文——高斯模糊算法 介绍的很不错主要涉及正态分布。不过我们现成的实现在网上找到这个JS插件——StackBlur.jsDemo地址http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html 。该插件可以实现高斯模糊效果主要使用里面的方法function stackBlurImage( imageID, canvasID, radius, blurAlphaChannel )其中 imageID 是html 页面中要高斯模糊的原图片标签IDcanvasID 是canvas 画图的IDradius 是要高斯模糊的半径blurAlphaChannel 涉及半透明(未详细研究)。于是敲定解决方案在html 页面中插入隐藏标签和隐藏的标签使用插件中方法设置作品展示的背景。方案敲定开始编码写完后上传了一张图片服务器保存后将图片地址保存后返回图片地址前端处理。测试通过完美兼容各大浏览器。问题出现在项目改造使用独立的图片服务器后图片服务器和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 之 transformCSS3 提供了很多变换其中 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 滤镜主要使用了 和 标记。保存一个名为 blur.svg 的SVG 文件文件内容如下xmlnshttp://www.w3.org/2000/svgxmlns:xlinkhttp://www.w3.org/1999/xlinkxmlns:evhttp://www.w3.org/2001/xml-eventsbaseProfilefull红色部位的代码便提供了一个高斯模糊滤镜(模糊半径为10) 标记提供了要模糊的图片属性 xlink:href 是图片的地址属性 filter 根据ID 应用了红色代码定义的滤镜然后SVG 作为背景图片载入.blur {background-image: url(blur.svg);}这样就达到了我们的目的——高斯模糊图片但仍然存在一个问题以上的SVG 文件单独于html 页面需要额外的维护要命的是图片的地址很难改变于是我们把以上 SVG 标签的内容作为内联元素放在了 html 页面中并和作品展示的容器同级。然后将他们的父元素 position 设为 relative 作品容器背景色设为透明。对 标签应用以下样式作为作品容器的背景width: 120%;height: 120%;position:absolute;top:-10%;left:-10%;最后是使用 JS 调节 标签中的 宽高属性以完美展示。至此问题得以解决。