使用Javascript扩大和侵蚀SVG形状 [英] Dilate and erode SVG shapes using Javascript

查看:235
本文介绍了使用Javascript扩大和侵蚀SVG形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:

我最终发现了一种腐蚀和扩大多边形(偏移)的方法,以便使用Clipper库创建新几何:
https://sourceforge.net/projects/jsclipper/



Javascript Clipper的现场演示:
http://jsclipper.sourceforge .net / 5.0.2.1 / main_demo.html



Clipper只能处理多边形或多边形(例如带孔的多边形),所以对于它要与其他SVG格式的图形对象一起使用,必须将它们转换为直线。至少使用 path.getTotalLength() path.getPointAtLength()(< href =http://whaticode.com/2012/02/01/converting-svg-paths-to-polygons/ =nofollow noreferrer> http://whaticode.com/2012/02/01/01转换-svg-paths-to-polygons / )。

另一种可能性是使用这种类似的技术(不会创建新的几何体):
https://stackoverflow.com/a/12723835/1691517






有没有什么方法可以通过Javascript在SVG中腐蚀和扩大形状?

我有以下SVG示例:
http://jsfiddle.net/timo2012/2S4Kt/1/


有三种形状,蓝色是原始的,绿色被侵蚀(变薄),红色被扩大(粗体)。它们是用Illustrator制作的。

我已经测试过腐蚀和扩张过滤器,但效果并不好:
https://dvcs.w3.org/hg/FXTF/raw-file/tip /filters/examples/feMorphology.svg



经过几个小时搜索互联网,我发现只有位图图像腐蚀和扩大的例子,但没有关于矢量

我成功地使用Shapely扩展和侵蚀SVG多边形(

这是我在Python中扩展和腐蚀的代码(正如你看到的那样短):

 #!/ usr / bin / python26 

from shapely.geometry从shapely.geometry中导入多边形
import MultiPolygon

import sys
$ b $ if len(sys.argv)> 2:
inset = eval(sys.argv [1])$ ​​b $ b coords = eval(sys.argv [2])
else:
sys.exit()

bowtie =多边形(coords)
clean = bowtie.buffer(插入)
clean = clean.simplify(1,preserve_topology = False)
if clean.length> 0:
if clean.geom_type ==MultiPolygon:
for n in范围(0,len(clean)):
print list(clean [n] .exterior.coords)
#print\\\

elif clean.geom_type ==Polygon :
print list(clean.exterior.coords)

另外找到这个文档,它尝试用数学术语来定义膨胀和腐蚀:
http://en.wikipedia.org/wiki / Mathematical_morphology



有一句话The bas二进制形态学中的思想是用简单的,预定义的形状探测图像,得出关于这种形状如何适合或错过图像形状的结论。这个简单的探测被称为结构元素,它本身就是一个二元图像(即空间或网格的一个子集)。



我认为这种方法可以用于变形矢量形状,但如何... ...编辑:在回复中的一个评论提出了使用过滤器,而不是创建新的几何可能的问题:如果有人想要将拖拽手柄添加到多边形点上,然后拖拽手柄看起来可能是错误的,这是可以接受的,因为这样的印象是原始路径数据是未触及的,这在滤波器中实际上是这种情况,但是 - 在进一步测试之后 - 它证明质量是一个更大的问题。根据这个 SVG滤镜使用矢量图形对象的像素表示而不是路径数据本身,这导致不太好看的结果



编辑2:可能的解决方法:此页面中的答案之一导致我使用可变宽度笔触和掩码来实现此问题的一个好看的解决方法。我做了一些测试,并实现了类似Adobe Illustrator的偏移路径效果

解决方案

你可以通过结合 clip-path 掩码。这里有一个示例,对它的结构进行了一些解释,参见 here and 这里(向上或向下箭头查看其他一些内容这个例子中的幻灯片)。



虽然它不会给你新的几何体,只是可能看起来像新的几何体。


EDIT:

I finally found a way to erode and dilate polygons (offsetting) so that new geometry is created using Clipper library: https://sourceforge.net/projects/jsclipper/

Live demo of Javascript Clipper: http://jsclipper.sourceforge.net/5.0.2.1/main_demo.html

The Clipper can only handle polygons or multi-polygons (eg. polygons with holes), so for it to work with other graphical objects of SVG format, they have to be converted to straight lines. At least paths are rather easy to convert to lines using path.getTotalLength() and path.getPointAtLength() (http://whaticode.com/2012/02/01/converting-svg-paths-to-polygons/).

The other possibility is use this like technique (that does not create new geometry): https://stackoverflow.com/a/12723835/1691517


Is there any way to erode and dilate shapes in SVG via Javascript?

I have the following SVG example: http://jsfiddle.net/timo2012/2S4Kt/1/

There are three shapes, blue is original, green is eroded (thinned) and red is dilated (bolded). They are made in Illustrator.

I have tested erode and dilate filters, but the effect is not so good: https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/examples/feMorphology.svg

After few hours searching over internet, I have found only examples about bitmap image eroding and dilating, but nothing about vector shapes.

I have succeeded in dilating and eroding SVG polygons using Shapely ( http://toblerity.github.com/shapely/manual.html ) in Python by sending path points via Ajax call to PHP script which makes system() call to Python script, but this method is slow and requires server to do the work that could be done client side.

This is my code for dilating and eroding in Python (as you see it is quite short):

#!/usr/bin/python26

from shapely.geometry import Polygon
from shapely.geometry import MultiPolygon

import sys

if len(sys.argv)>2:
  inset=eval(sys.argv[1])
  coords=eval(sys.argv[2])
else:
  sys.exit()

bowtie = Polygon(coords)
clean = bowtie.buffer(inset)
clean = clean.simplify(1, preserve_topology=False)
if clean.length>0:
  if clean.geom_type=="MultiPolygon":
    for n in range(0, len(clean)):
      print list(clean[n].exterior.coords)
      #print "\n"
  elif clean.geom_type=="Polygon":
    print list(clean.exterior.coords)

Also find this document, which tries to define dilate and erode in mathematical terms: http://en.wikipedia.org/wiki/Mathematical_morphology

There is a sentence "The basic idea in binary morphology is to probe an image with a simple, pre-defined shape, drawing conclusions on how this shape fits or misses the shapes in the image. This simple "probe" is called structuring element, and is itself a binary image (i.e., a subset of the space or grid)."

I assume that this method could be used in morphing vector shapes, but how...

EDIT: One comment in a reply raised a possible issue of using filters instead of creating new geometry: if someone wants to add drag handles to polygon points, then drag handles may seem to be in wrong place. This can be acceptable, because then the impression is that the original path data is untouched, which is actually the case in filters, but - after further testing - it proved that the quality is a bigger problem. According to this and this SVG filter uses pixel representation of vector graphic object instead of path data itself, which leads to not so good looking results.

EDIT2: POSSIBLE WORKAROUND: One of the answers in this page led me to use variable-width strokes and mask to achieve a good looking workaround to this issue. I made a few tests and get implemented an Adobe Illustrator -like Offset Path Effect.

解决方案

You can sort of get what you seem to be after by stroking with different stroke-widths in combination with clip-path or mask. Here's an example, some explanations of how it's constructed see here and here (arrow up or down to see some other slides on that example).

It doesn't give you new geometry though, just something that might look like new geometry.

这篇关于使用Javascript扩大和侵蚀SVG形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆