我有一个SVG图像,我想从中提取几个矩形区域作为独立的SVG图像。因为原始图像相当大,但与感兴趣区域相交的元素很小,我不希望完全位于裁剪的viewBox
之外的元素保留在裁剪的SVG图像中。
从概念上讲,我正在寻找的是:
裁剪的SVG(是的,输出必须是 SVG ,而不是位图)不应包含螺旋或星形的元素,因为它们完全落在感兴趣的区域之外。 (是的,非连接元素确实必须被删除,因为源SVG比裁剪的SVG多几个数量级,因为我打算以不同的方式裁剪数百次。)我希望能够指定由于要生成相当多的裁剪图像,命令行中感兴趣的区域也是如此。
有没有可以做到这一点的工具?
答案 0 :(得分:0)
可以在svg rect对象内部和/或与rect对象相交的情况下解析SVG元素并将其标记为true / false。 这对你有用吗?
isEnclosed = mySVG.checkEnclosure(myElement, RectObj)
doesIntersect = mySVG.checkIntersection(myElement, RectObj)
答案 1 :(得分:0)
我使用Jordan Curve定理来测试svg多边形内的点。您的多边形将是您的viewBox。如果每个元素都有一个与之关联的目标点(即中心点)以确定是否要显示它,那么这可能对您有用。 以下是我使用的javascript :(警告:我认为多边形应该有逆时针点。在处理多边形时总是一个好主意)
//---Point-in-polygon: Jordan Curve Theorem---
function pointInPolygon(myPolygon,px,py)
{
var pointsList=myPolygon.points
var x
var y
var x1
var y1
var crossings=0
var verts=pointsList.numberOfItems
//---Iterate through each line ---
for ( var i = 0; i < verts; i++ )
{
var vertx=pointsList.getItem(i).x
var verty=pointsList.getItem(i).y
if(i<verts-1)
{
var vertxNext=pointsList.getItem(i+1).x
var vertyNext=pointsList.getItem(i+1).y
}
else
{
var vertxNext=pointsList.getItem(0).x
var vertyNext=pointsList.getItem(0).y
}
/* This is done to ensure that we get the same result when
the line goes from left to right and right to left */
if ( vertx < vertxNext){
x1 = vertx;
x2 = vertxNext;
} else {
x1 = vertxNext;
x2 = vertx;
}
/* First check if the ray is possible to cross the line */
if ( px > x1 && px <= x2 && ( py < verty || py <= vertyNext ) ) {
var eps = 0.000000001;
/* Calculate the equation of the line */
var dx = vertxNext - vertx;
var dy = vertyNext - verty;
var k;
if ( Math.abs(dx) < eps ){
k = Infinity;
} else {
k = dy/dx;
}
var m = verty - k * vertx;
/* Find if the ray crosses the line */
y2 = k * px + m;
if ( py <= y2 ){
crossings++;
}
}
}
//---odd number of crossings: point inside polygon--
var crossFlag=(crossings/2)+""
if(crossFlag.indexOf(".")!=-1)
return true;
else
return false;
}
答案 2 :(得分:0)
由于您的svg元素已转换,您可能需要将它们转换为屏幕点。我已经使用以下javascript为各种svg元素(线,矩形,圆形,椭圆,多边形,折线和路径)
//----build a generic document SVG root to hold svg point---
function screenLine(line,svg)
{
var sCTM = line.getCTM()
var x1=parseFloat(line.getAttribute("x1"))
var y1=parseFloat(line.getAttribute("y1"))
var x2=parseFloat(line.getAttribute("x2"))
var y2=parseFloat(line.getAttribute("y2"))
var mySVGPoint1 = svg.createSVGPoint();
mySVGPoint1.x = x1
mySVGPoint1.y = y1
mySVGPointTrans1 = mySVGPoint1.matrixTransform(sCTM)
line.setAttribute("x1",mySVGPointTrans1.x)
line.setAttribute("y1",mySVGPointTrans1.y)
var mySVGPoint2 = svg.createSVGPoint();
mySVGPoint2.x = x2
mySVGPoint2.y = y2
mySVGPointTrans2= mySVGPoint2.matrixTransform(sCTM)
line.setAttribute("x2",mySVGPointTrans2.x)
line.setAttribute("y2",mySVGPointTrans2.y)
//---force removal of transform--
line.setAttribute("transform","")
line.removeAttribute("transform")
}
function screenCircle(circle,svg)
{
var sCTM = circle.getCTM()
var scaleX = sCTM.a;
var cx=parseFloat(circle.getAttribute("cx"))
var cy=parseFloat(circle.getAttribute("cy"))
var r=parseFloat(circle.getAttribute("r"))
var mySVGPointC = svg.createSVGPoint();
mySVGPointC.x = cx
mySVGPointC.y = cy
mySVGPointTransC = mySVGPointC.matrixTransform(sCTM)
circle.setAttribute("cx",mySVGPointTransC.x)
circle.setAttribute("cy",mySVGPointTransC.y)
circle.setAttribute("r",r*scaleX)
//---force removal of transform--
circle.setAttribute("transform","")
circle.removeAttribute("transform")
}
function screenEllipse(ellipse,svg)
{
var sCTM = ellipse.getCTM()
var scaleX = sCTM.a;
var scaleY = sCTM.d;
var cx=parseFloat(ellipse.getAttribute("cx"))
var cy=parseFloat(ellipse.getAttribute("cy"))
var rx=parseFloat(ellipse.getAttribute("rx"))
var ry=parseFloat(ellipse.getAttribute("ry"))
var mySVGPointC = svg.createSVGPoint();
mySVGPointC.x = cx
mySVGPointC.y = cy
mySVGPointTransC = mySVGPointC.matrixTransform(sCTM)
ellipse.setAttribute("cx",mySVGPointTransC.x)
ellipse.setAttribute("cy",mySVGPointTransC.y)
ellipse.setAttribute("rx",rx*scaleX)
ellipse.setAttribute("ry",ry*scaleY)
//---force removal of transform--
ellipse.setAttribute("transform","")
ellipse.removeAttribute("transform")
}
function screenRect(rect,svg)
{
var sCTM = rect.getCTM()
var scaleX = sCTM.a;
var scaleY = sCTM.d;
var x=parseFloat(rect.getAttribute("x"))
var y=parseFloat(rect.getAttribute("y"))
var width=parseFloat(rect.getAttribute("width"))
var height=parseFloat(rect.getAttribute("height"))
var mySVGPoint = svg.createSVGPoint();
mySVGPoint.x = x
mySVGPoint.y = y
mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
rect.setAttribute("x",mySVGPointTrans.x)
rect.setAttribute("y",mySVGPointTrans.y)
rect.setAttribute("width",width*scaleX)
rect.setAttribute("height",height*scaleY)
//---force removal of transform--
rect.setAttribute("transform","")
rect.removeAttribute("transform")
}
function screenPolyline(myPoly,svg)
{
var sCTM = myPoly.getCTM()
var pointsList = myPoly.points;
var n = pointsList.numberOfItems;
for(var m=0;m<n;m++)
{
var mySVGPoint = mySVG.createSVGPoint();
mySVGPoint.x = pointsList.getItem(m).x
mySVGPoint.y = pointsList.getItem(m).y
mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
pointsList.getItem(m).x=mySVGPointTrans.x
pointsList.getItem(m).y=mySVGPointTrans.y
}
//---force removal of transform--
myPoly.setAttribute("transform","")
myPoly.removeAttribute("transform")
}
function screenPath(path,svg)
{
var sCTM = path.getCTM()
var scaleX = sCTM.a;
var scaleY = sCTM.d;
var segList=path.pathSegList
var segs=segList.numberOfItems
//---change segObj values
for(var k=0;k<segs;k++)
{
var segObj=segList.getItem(k)
if(segObj.x && segObj.y )
{
var mySVGPoint = svg.createSVGPoint();
mySVGPoint.x = segObj.x
mySVGPoint.y = segObj.y
mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
segObj.x=mySVGPointTrans.x
segObj.y=mySVGPointTrans.y
}
if(segObj.x1 && segObj.y1)
{
var mySVGPoint1 = svg.createSVGPoint();
mySVGPoint1.x = segObj.x1
mySVGPoint1.y = segObj.y1
mySVGPointTrans1 = mySVGPoint1.matrixTransform(sCTM)
segObj.x1=mySVGPointTrans1.x
segObj.y1=mySVGPointTrans1.y
}
if(segObj.x2 && segObj.y2)
{
var mySVGPoint2 = svg.createSVGPoint();
mySVGPoint2.x = segObj.x2
mySVGPoint2.y = segObj.y2
mySVGPointTrans2 = mySVGPoint2.matrixTransform(sCTM)
segObj.x2=mySVGPointTrans2.x
segObj.y2=mySVGPointTrans2.y
}
if(segObj.r1)segObj.r1=segObj.r1*scaleX
if(segObj.r2)segObj.r2=segObj.r2*scaleX
}
//---force removal of transform--
path.setAttribute("transform","")
path.removeAttribute("transform")
}
//---changes all transformed points to screen points---
function screenPolygon(myPoly,mySVG)
{
var sCTM = myPoly.getCTM()
var pointsList = myPoly.points;
var n = pointsList.numberOfItems;
for(var m=0;m<n;m++)
{
var mySVGPoint = mySVG.createSVGPoint();
mySVGPoint.x = pointsList.getItem(m).x
mySVGPoint.y = pointsList.getItem(m).y
mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
pointsList.getItem(m).x=mySVGPointTrans.x
pointsList.getItem(m).y=mySVGPointTrans.y
}
//---force removal of transform--
myPoly.setAttribute("transform","")
myPoly.removeAttribute("transform")
}