[关闭]
@Gizmosir 2016-03-22T09:00:21.000000Z 字数 10515 阅读 700

date: 2016-03-17
categories: Computer graphics
tag: [SVG, 矢量图]
博客

title: 矢量图像进阶技巧(II)

前言

这是矢量图的第三篇,如果你先看前两篇,可以点击这里这里

在上一篇中我们介绍了一部分SVG滤镜组件,在这一篇中我们将继续来介绍滤镜组件以及它们的使用方式。

滤镜

色彩矩阵(feColorMatrix)

在上一篇中我们介绍过色彩调节的方法,使用的是feComponentTransfer。这里我们介绍另外一个更加方便地调节色彩的方法feColorMatrix。不同的地方是feComponentTransfer使用直线/曲线来调整图像的RGBA值,而feColorMatrix不仅可以使用矩阵来调整图像的RGBA值,还可以整体地调整HSV值。

更多关于RGBA与HSV色彩系统的差别请点击这里

色彩矩阵的含义:

  1. <!--本例子中,我们首先生成了一个色彩矩阵滤镜,并将该滤镜应
  2. 用到读取的图片上,最后我们与原图对比效果。-->
  3. <svg
  4. xmlns="http://www.w3.org/2000/svg"
  5. xmlns:xlink="http://www.w3.org/1999/xlink" >
  6. <defs>
  7. <filter id="grayscale" color-interpolation-filters="sRGB">
  8. <feColorMatrix type="matrix" in="SourceGraphic"
  9. values=".33 .33 .33 0 0
  10. .33 .33 .33 0 0
  11. .33 .33 .33 0 0
  12. 0 0 0 1 0" />
  13. </filter>
  14. </defs>
  15. <text x="10" y="155">Before:</text>
  16. <image x="70" y="10" width="401" height="301"
  17. xlink:href="colours.jpg" />
  18. <text x="510" y="155">After:</text>
  19. <image x="570" y="10"
  20. width="401"
  21. height="301"
  22. xlink:href="colours.jpg"
  23. style="filter:url(#grayscale)" />
  24. </svg>

需要说明的是,在以上代码中我们将色彩矩阵声明为:

也就是将使得每个点的R、G、B值都相等。RGB色彩空间可以用下面的“色彩立方体”来表示,从图中我们能够很清晰地发现,R、G、B值都相同的点,就是图中原点(黑)到W(白)的对角线。

feColorMatrix除了能够使用色彩矩阵外,还能用hueRotate来调整图像色彩。Hue的色彩空间如下:

  1. <!--本例子中首先定义了三个色彩矩阵滤镜,分别把Hue旋转90度
  2. 、180度和270度,然后将三个滤镜分别应用到读取的图像上,最后
  3. 对比原图和三个滤镜处理后的图像。-->
  4. <svg
  5. xmlns="http://www.w3.org/2000/svg"
  6. xmlns:xlink="http://www.w3.org/1999/xlink" >
  7. <defs>
  8. <filter id="add_90" color-interpolation-filters="sRGB">
  9. <feColorMatrix type="hueRotate" in="SourceGraphic"
  10. values="90" />
  11. </filter>
  12. <filter id="add_180" color-interpolation-filters="sRGB">
  13. <feColorMatrix type="hueRotate" in="SourceGraphic"
  14. values="180" />
  15. </filter>
  16. <filter id="add_270" color-interpolation-filters="sRGB">
  17. <feColorMatrix type="hueRotate" in="SourceGraphic"
  18. values="270" />
  19. </filter>
  20. </defs>
  21. <text x="10" y="145">Before:</text>
  22. <image x="70" y="0" width="400" height="300"
  23. xlink:href="brown.jpg" />
  24. <text x="510" y="145">+90:</text>
  25. <image x="570" y="0"
  26. width="400"
  27. height="300"
  28. xlink:href="brown.jpg"
  29. style="filter:url(#add_90)" />
  30. <text x="10" y="600">+180:</text>
  31. <image x="70" y="340"
  32. width="400"
  33. height="300"
  34. xlink:href="brown.jpg"
  35. style="filter:url(#add_180)" />
  36. <text x="510" y="545">+270:</text>
  37. <image x="570" y="340"
  38. width="400"
  39. height="300"
  40. xlink:href="brown.jpg"
  41. style="filter:url(#add_270)" />
  42. </svg>

同样的还能使用feColorMatrix来调整图像的饱和度。

  1. <!--本例子中首先生成一个改善饱和度的色彩矩阵滤镜,并将其应
  2. 用到读取的图片上。-->
  3. <svg
  4. xmlns="http://www.w3.org/2000/svg"
  5. xmlns:xlink="http://www.w3.org/1999/xlink" >
  6. <defs>
  7. <filter id="increase_s" color-interpolation-filters="sRGB">
  8. <feColorMatrix type="saturate" in="SourceGraphic" values="1.4"/>
  9. </filter>
  10. </defs>
  11. <text x="10" y="190">Before:</text>
  12. <image x="70" y="10" width="399" height="389"
  13. xlink:href="woman_face.jpg" />
  14. <text x="530" y="190">S=S*1.4:</text>
  15. <image x="600" y="10"
  16. width="399"
  17. height="389"
  18. xlink:href="woman_face.jpg"
  19. style="filter:url(#increase_s)" />
  20. </svg>

图像卷积(feConvolveMatrix)

图像处理中一个非常重要的工具是图像卷积。使用卷积我们能够实现模糊,边缘检测等图像处理效果。SVG中当然也包含如此重要的工具:feConvolveMatrix

  1. <!--本例子中,首先生成一个3x3的卷积矩阵滤镜,然后将滤镜应
  2. 用到图像上生成最后的图像。值得注意的是卷积矩阵为拉普拉斯高
  3. 通卷积,换句话说就是保留图像的高频信息,也就是边缘。-->
  4. <svg
  5. xmlns="http://www.w3.org/2000/svg"
  6. xmlns:xlink="http://www.w3.org/1999/xlink" >
  7. <defs>
  8. <filter id="convolve_edge"
  9. color-interpolation-filters="sRGB">
  10. <feConvolveMatrix
  11. in="SourceGraphic"
  12. kernelMatrix="0 1 0 1 -4 1 0 1 0"
  13. order="3 3"
  14. divisor="1"
  15. bias="0"
  16. preserveAlpha="true" />
  17. </filter>
  18. </defs>
  19. <image width="300" height="300" xlink:href="squares.png" />
  20. <text x="320" y="145">- after feConvolveMatrix:</text>
  21. <image x="500" width="300" height="300"
  22. xlink:href="squares.png"
  23. style="filter:url(#convolve_edge)" />
  24. </svg>

混沌(feTurbulence)

在SVG中我们常常需要用到随机值,而一个常用于产生随机数的工具就是feTurbulence。其有两种不同的效果(fractalNoise | turbulence),如下所示:

左图为fractalNoise效果,右图为turbulence效果。从上图不能看出fractalNoise稍微平衡些,turbulence波动更大些。

题外话:混沌的名字是我自己起的,因为实在找不到翻译的地方。而实际图像效果也很像宇宙之初混沌状态不是么?

  1. <!--本例子中,首先我们生成了一个混沌滤镜,并且与蓝色矩形复
  2. 并生成最后的图像。值得注意的是这里混沌滤镜的numOctaves为4
  3. ,也就是只有alpha值。-->
  4. <svg
  5. xmlns="http://www.w3.org/2000/svg"
  6. xmlns:xlink="http://www.w3.org/1999/xlink" >
  7. <defs>
  8. <filter id="sky">
  9. <feTurbulence
  10. type="fractalNoise"
  11. baseFrequency="0.005"
  12. numOctaves="4"
  13. seed="0"
  14. result="noise" />
  15. <feComposite in="SourceGraphic" in2="noise" operator="in" />
  16. </filter>
  17. </defs>
  18. <rect x="0" y="0"
  19. width="800" height="600"
  20. style="fill:blue;filter:url(#sky)" />
  21. </svg>

值得注意的是,就如同我们之前说的那样,feTurbulence滤镜是很多SVG实现效果的基础。同时还展示了在上一篇中我们并没有展示feComposite的效果。需要留意的是在这里我们使用的是in属性,也就是只展示后图层与前图层共用的部分。

如果将蓝色矩形换成蓝色的文本,那么我们又得到一种新的文本效果,蓝色云状!

  1. <!--本例子代码与上个例子的代码几乎完全一致,只是修改了最后
  2. 的代码将蓝色的矩形换成蓝色的文本。-->
  3. <svg
  4. xmlns="http://www.w3.org/2000/svg"
  5. xmlns:xlink="http://www.w3.org/1999/xlink" >
  6. <defs>
  7. <filter id="sky">
  8. <feTurbulence
  9. type="fractalNoise"
  10. baseFrequency="0.005"
  11. numOctaves="4"
  12. seed="0"
  13. result="noise" />
  14. <feComposite in="SourceGraphic" in2="noise" operator="in" />
  15. </filter>
  16. </defs>
  17. <text x="100" y="200" font-size="150" font-family="Arial"
  18. style="fill:blue;filter:url(#sky)" >
  19. Blue sky text
  20. </text>
  21. </svg>

  1. <!--本例子中首先生成一个混沌滤镜,然后对其进行色彩矩阵调整
  2. ,使得其红色和黄色增强,最后复合到红色背景的文本上并生成最
  3. 后的图像。值得注意的是混沌滤镜numOctaves值为1,也就是只需
  4. 要了R值。另外通过style="background-color:
  5. red"将背景色定义为红色。所以通过文本后看到的是红色的背景。-->
  6. <svg
  7. xmlns="http://www.w3.org/2000/svg"
  8. xmlns:xlink="http://www.w3.org/1999/xlink"
  9. style="background-color: red">
  10. <defs>
  11. <filter id="fire"
  12. color-interpolation-filters="sRGB">
  13. <feTurbulence
  14. type="fractalNoise"
  15. baseFrequency="0.013 0.003"
  16. numOctaves="1"
  17. />
  18. <feColorMatrix
  19. type="matrix"
  20. values="0 0 0 0 1
  21. 1.5 0 0 0 0
  22. 0 0 0 0 0
  23. 5 0 0 0 0"
  24. result="color_transformed" />
  25. <feComposite in="color_transformed"
  26. in2="SourceGraphic"
  27. operator="out" />
  28. </filter>
  29. </defs>
  30. <text x="0" y="300" font-size="350" font-family="Arial"
  31. style="filter:url(#fire)" > Fire! </text>
  32. </svg>

值得留意的是在这里feComposite我们使用的是out属性,也就是只展示前图层有而后图层没有的部分。在这个例子中,前图层是“火焰”混沌滤镜,后图层是文本。所有后图层文本的部分不显示了,也就能够透过去看到红色背景。

题外话:也许你发现我已经提及了很多种不同的文字效果,的确如此,一是因为文字效果更为常用,二是易于展示不同的滤镜效果。唯为多尝试才能了解不同的滤镜的细微差别。

位移(feDisplacement)

在上一篇中我们介绍了偏移滤镜组件feOffset,其功能是将图形/图像整体往X/Y轴偏移。现在我们介绍一个可以单独移动每个“像素”的滤镜组件feDisplacement

  1. <!--本例子中,首先定义了一个形如上图的渐变滤镜,并该滤镜应
  2. 用到到矩形中,接着用这个渐变矩形来改变文本的Y轴文字并最终
  3. 生成图像效果。-->
  4. <svg
  5. xmlns="http://www.w3.org/2000/svg"
  6. xmlns:xlink="http://www.w3.org/1999/xlink" >
  7. <defs>
  8. <linearGradient id="gradient1">
  9. <stop offset= "0" style= "stop-color:white"/>
  10. <stop offset=".1" style= "stop-color:black"/>
  11. <stop offset=".2" style= "stop-color:white"/>
  12. <stop offset=".3" style= "stop-color:black"/>
  13. <stop offset=".4" style= "stop-color:white"/>
  14. <stop offset=".5" style= "stop-color:black"/>
  15. <stop offset=".6" style= "stop-color:white"/>
  16. <stop offset=".7" style= "stop-color:black"/>
  17. <stop offset=".8" style= "stop-color:white"/>
  18. <stop offset=".9" style= "stop-color:black"/>
  19. <stop offset="1.0" style= "stop-color:white"/>
  20. </linearGradient>
  21. <rect width="800" height="400" fill="url(#gradient1)" id="gradient_area" />
  22. <filter id="waves_filter" color-interpolation-filters="sRGB">
  23. <feImage xlink:href="#gradient_area" result="displacement_information"/>
  24. <feDisplacementMap
  25. in="SourceGraphic"
  26. in2="displacement_information"
  27. <!--只改变了文本的Y轴方向-->
  28. <!--由于渐变滤镜是灰度值,所以无所谓RGB哪个值-->
  29. yChannelSelector="R"
  30. scale="15" >
  31. </feDisplacementMap>
  32. </filter>
  33. </defs>
  34. <text x="0" y="100" font-size="80pt" font-family="Arial"
  35. fill="darkblue" style="filter:url(#waves_filter)">
  36. <tspan x="10">Take the</tspan>
  37. <tspan x="60" dy="120">Star Ferry!</tspan>
  38. </text>
  39. </svg>

的确feDisplacementMap由于涉及到很多东西,所以例子没有那么简单明了不易理解,那么我们就多看几个例子把。

  1. <!--本例子与上个例子很类似,只是将线性渐变换成了径向渐变,
  2. 所以feDisplacementMap的移动也变成了X轴Y轴同时移动。-->
  3. <svg
  4. xmlns="http://www.w3.org/2000/svg"
  5. xmlns:xlink="http://www.w3.org/1999/xlink" >
  6. <defs>
  7. <radialGradient id="gradient1">
  8. <stop offset= "0" style= "stop-color:white"/>
  9. <stop offset=".1" style= "stop-color:black"/>
  10. <stop offset=".2" style= "stop-color:white"/>
  11. <stop offset=".3" style= "stop-color:black"/>
  12. <stop offset=".4" style= "stop-color:white"/>
  13. <stop offset=".5" style= "stop-color:black"/>
  14. <stop offset=".6" style= "stop-color:white"/>
  15. <stop offset=".7" style= "stop-color:black"/>
  16. <stop offset=".8" style= "stop-color:white"/>
  17. <stop offset=".9" style= "stop-color:black"/>
  18. <stop offset="1.0" style= "stop-color:white"/>
  19. </radialGradient>
  20. <rect width="1000" height="450" fill="url(#gradient1)" id="gradient_area" />
  21. <filter id="fracture_filter" color-interpolation-filters="sRGB">
  22. <feImage xlink:href="#gradient_area" result="displacement_information"/>
  23. <feDisplacementMap
  24. in="SourceGraphic"
  25. in2="displacement_information"
  26. <!--在X轴和Y轴上发送位移-->
  27. <!--由于渐变滤镜是灰度值,所以无所谓RGB哪个值-->
  28. xChannelSelector="R"
  29. yChannelSelector="R"
  30. scale="15" >
  31. </feDisplacementMap>
  32. </filter>
  33. </defs>
  34. <text x="0" y="100" font-size="80pt" font-family="Arial"
  35. style="filter:url(#fracture_filter)">
  36. <tspan x="60"> Fractured</tspan>
  37. <tspan x="30" dy="90">Information</tspan>
  38. </text>
  39. </svg>

接下来我们来看一个比较酷炫的例子:

  1. <!--本例子中我们定义了一个“太阳”渐变滤镜,并将其应用到矩形
  2. 中,接着我们生成一个混沌滤镜,最后将太阳滤镜根据混沌滤镜的
  3. 值来做位移并生成最后的效果图像。有点复杂,结合着代码和下面
  4. 的流程图多揣摩揣摩。-->
  5. <svg
  6. xmlns="http://www.w3.org/2000/svg"
  7. xmlns:xlink="http://www.w3.org/1999/xlink"
  8. style="background-color: black" >
  9. <defs>
  10. <filter id="explode"
  11. color-interpolation-filters="sRGB">
  12. <feTurbulence
  13. type="fractalNoise"
  14. baseFrequency="0.02"
  15. numOctaves="4"
  16. result="noise" />
  17. <feDisplacementMap
  18. in="SourceGraphic"
  19. in2="noise"
  20. scale="150"
  21. <!--其实RGB值如何用的无所谓-->
  22. xChannelSelector="R"
  23. yChannelSelector="B" />
  24. </filter>
  25. <radialGradient id="sun_gradient" cx="400" cy="400"
  26. r="350" gradientUnits="userSpaceOnUse">
  27. <stop offset="0" stop-color="red"/>
  28. <stop offset="0.1" stop-color="red"/>
  29. <stop offset="0.4" stop-color="yellow"/>
  30. <stop offset="0.8" stop-color="orange"/>
  31. <stop offset="1" stop-color="lightorange" />
  32. </radialGradient>
  33. </defs>
  34. <!--这里生成一个矩形,然后先用“太阳”渐变滤镜填充,然后在使用由混沌滤镜生成的位移滤镜-->
  35. <rect x="0" y="0" height="800" width="800"
  36. fill="url(#sun_gradient)" filter="url(#explode)"/>
  37. </svg>

光照(Light)

在显示生活中,光照是影响图片效果的很重要的部分。毫无例外的SVG也包含不同的光照滤镜组件( feDiffueseLighting | feSpecularLighting | feDistantLight | fePointLight | feSpotLight ),其效果如下:

  1. <!--本例子中,首先生成一个混沌滤镜,接着一边根据混沌滤镜来
  2. 生成一个位移滤镜,另一边根据混论滤镜还生成光照滤镜,最后将
  3. 两个滤镜同时应用到黄色矩形上并最终生成揉皱的黄色纸张的效果。-->
  4. <svg
  5. xmlns="http://www.w3.org/2000/svg"
  6. xmlns:xlink="http://www.w3.org/1999/xlink" >
  7. <defs>
  8. <filter id="recycled_paper"
  9. color-interpolation-filters="sRGB">
  10. <feTurbulence
  11. type="fractalNoise"
  12. baseFrequency="0.04"
  13. numOctaves="5"
  14. seed="0"
  15. result="noise" />
  16. <feDisplacementMap
  17. in="SourceGraphic"
  18. in2="noise"
  19. result="displaced_image"
  20. yChannelSelector="G"
  21. xChannelSelector="R"
  22. scale="10" />
  23. <feDiffuseLighting
  24. in="noise"
  25. result="noise_with_lighting"
  26. lighting-color="rgb(233,230,215)"
  27. diffuseConstant="1"
  28. surfaceScale="2" >
  29. <feDistantLight
  30. azimuth="235"
  31. elevation="40" />
  32. </feDiffuseLighting>
  33. <feComposite
  34. in="displaced_image"
  35. in2="noise_with_lighting"
  36. result="combined_result"
  37. <!--自定义两个滤镜结合的方法-->
  38. operator="arithmetic"
  39. k1="1.7" />
  40. </filter>
  41. </defs>
  42. <rect x="100" y="100"
  43. width="600" height="400"
  44. style="fill:#ffd42a;filter:url(#recycled_paper)" />
  45. </svg>

总结

那么基本上我们就将所有的滤镜组件都介绍了一遍,我相信你对不同滤镜的效果和使用方法也有个大概的了解。当然这么多滤镜肯定是无法一下子都掌握的,唯有自己多动手试试。下篇我将结合之前介绍过的SVG基础技巧与进阶技巧,来制作一张属于你自己的个性名片!

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注