我最近发现这个惊人的课程位于here,并尝试使用它。
但是,它仅适用于某些基本功能,如移动,水平线和垂直线。
-
我尝试通过添加其他检查(并更改正则表达式)来扩展此现有类。
public static function fromPath($pathString) {
preg_match_all('/([mlvhzc][^mlvhzc]*)/i', $pathString, $commands);
$pt = array(0, 0);
$bounds = new self();
foreach ($commands[0] as $command) {
preg_match_all('/((\+|-)?\d+(\.\d+)?(e(\+|-)?\d+)?)/i', $command, $matches);
$i = 0;
while ($i < count($matches[1])) {
switch ($command[0]) {
case 'm' :
case 'l' :
$pt[0] += $matches[1][$i++];
$pt[1] += $matches[1][$i++];
break;
case 'M' :
case 'L' :
$pt[0] = $matches[1][$i++];
$pt[1] = $matches[1][$i++];
$last=$pt;
break;
case 'v' :
$pt[1] += $matches[1][$i++];
break;
case 'V' :
$pt[1] = $matches[1][$i++];
$last[1]=$pt[1];
break;
case 'h' :
$pt[0] += $matches[1][$i++];
break;
case 'H' :
$pt[0] = $matches[1][$i++];
$last[0]=$pt[0];
break;
case 'z' :
case 'Z' :
break;
case 'c':
$pt[0] = $last[0]+$matches[1][4];
$pt[1] = $last[1]+$matches[1][5];
$last=$pt;
$i=count($matches[1]);
break;
default :
throw new RuntimeException("Unhandled path command: " . $command[0]);
}
$bounds->extend($pt[0], $pt[1]);
}
}
return $bounds;
}
我检查了SVG手册并发现'c'只有6个参数,知道最后2个是曲线最终的位置,我试图根据这个点扩展点......
目前,我的测试基于此:
<svg xmlns="http://www.w3.org/2000/svg" width="109" height="109" viewBox="0 0 109 109">
<g style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;">
<path d="M32.25,41c1.25,0.62,3.12,0.67,5.5,0.5c7.12-0.5,19.12-2.5,24-3c0.99-0.1,2.62-0.25,3.75,0" />
</g>
当在浏览器中运行时,Chrome会报告它的宽高比(因为我知道svg并不完全具有大小),大约是5到6,但是,当我找到与我的脚本的比率时,它完全关闭
我想知道是否有另一个svg类支持所有函数(C,c,Q,q等)。
我知道有一种方法可以通过将其转换为图像来获取框,但我觉得效率低,而且javascript中也有getBBox,但我想在服务器上执行计算。
感谢阅读!
答案 0 :(得分:3)
这是一个使用imagick的例子,它实际上是两个例子,因为它们不能同时运行,当时取消注释:
$svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="109" height="109" viewBox="0 0 109 109">
<g style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;">
<path d="M32.25,41c1.25,0.62,3.12,0.67,5.5,0.5c7.12-0.5,19.12-2.5,24-3c0.99-0.1,2.62-0.25,3.75,0" />
</g>
</svg>';
$im = new Imagick();
$im->readImageBlob($svg);
$im->trimImage (0);//This trims the unecessary blank space.
//This block gets the dimensions (comment this block before uncommenting the second example bellow)
$dimension = $im->getImageGeometry();
print_r('<pre>');
print_r($dimension);
die();
/*//Uncomment this block to view thw jpeg version of the svg
$im->setImageFormat("jpeg");
header("Content-Type: image/jpeg");
$thumbnail = $im->getImageBlob();
echo $thumbnail;
$im->clear();
$im->destroy();
//*/
答案 1 :(得分:1)
Hermann's answer给了我很多帮助,但实际上并没有削减SVG。以下是我根据他的回答找到的第一个解决方案:
function getTrimmedSvg( $filePath )
{
$image = new Imagick();
$image->readImage( $filePath );
$image->trimImage( 0 );
$imagePage = $image->getImagePage();
$dimensions = $image->getImageGeometry();
$minXOut = $imagePage['x'];
$minYOut = $imagePage['y'];
$widthOut = $dimensions["width"];
$heightOut = $dimensions["height"];
$xml = simplexml_load_file( $filePath );
$xml["viewBox"] = "$minXOut $minYOut $widthOut $heightOut";
return $xml->asXML();
}
虽然这在大多数时间都有效,但它并不是一直都在工作。在尝试修复边缘情况之后,我花了很多徒劳的努力,转而使用名为svg-bounding-box(GitHub)的nodejs命令行实用程序。这照顾了我所有的边缘情况。在服务器和/或开发环境中全局安装svg-bounding-box后,可以这样在代码中使用它:
function getTrimmedSvg( $filePath )
{
$xml = simplexml_load_file( $filePath );
$xml["viewBox"] = shell_exec( "cat $filePath | svg-bounding-box" );
return $xml->asXML();
}