如何在PHP中去除SVG文件中的空白区域?
如何去除SVG文件中的空白区域?
以下是我的SVG文件:
<svg xmlns="http://www.w3.org/2000/svg" fill="none" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin:auto;display:block;" width="100" height="100" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"> <rect width="100%" height="100%" fill="none"/> <circle cx="72" cy="50" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.9s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.9s"></animate> </circle> <circle cx="67.79837387624885" cy="62.93127555043441" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.8s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.8s"></animate> </circle> <circle cx="56.798373876248846" cy="70.92324335849338" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.7s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.7s"></animate> </circle> <circle cx="43.20162612375116" cy="70.92324335849338" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.6s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.6s"></animate> </circle> <circle cx="32.201626123751154" cy="62.931275550434414" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.5s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.5s"></animate> </circle> <circle cx="28" cy="50" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.4s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.4s"></animate> </circle> <circle cx="32.201626123751154" cy="37.06872444956559" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.3s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.3s"></animate> </circle> <circle cx="43.201626123751154" cy="29.076756641506623" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.2s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.2s"></animate> </circle> <circle cx="56.79837387624884" cy="29.07675664150662" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="-0.1s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="-0.1s"></animate> </circle> <circle cx="67.79837387624885" cy="37.068724449565586" fill="#007a5c" r="4"> <animate attributeName="r" values="2.4;2.4;4;2.4;2.4" times="0;0.1;0.2;0.3;1" dur="1s" repeatCount="indefinite" begin="0s"></animate> <animate attributeName="fill" values="#007a5c;#007a5c;#125443;#007a5c;#007a5c" repeatCount="indefinite" times="0;0.1;0.2;0.3;1" dur="1s" begin="0s"></animate> </circle> </svg>
我曾使用ImageMagick处理,但效果不佳,希望了解在PHP中的解决方法。
PHP解决方法
要去除SVG的空白区域,核心是重新计算viewBox属性,让它刚好包裹所有图形元素,同时按需调整width和height属性。以下是具体实现步骤和代码:
1. 核心思路
- 解析SVG文件,遍历所有图形元素,计算它们的最小包围盒(所有元素的最小/最大X、Y坐标)
- 根据包围盒更新
viewBox属性,让SVG视图区域精准适配图形范围 - 可选:调整SVG的
width和height为包围盒的实际尺寸,或保留原尺寸并通过preserveAspectRatio适配
2. 示例代码
针对你的SVG(仅包含圆形元素),可以用以下代码处理:
<?php // 读取SVG内容,替换为你的文件路径或直接传入内容 $svgContent = file_get_contents('your-svg-file.svg'); $dom = new DOMDocument(); libxml_use_internal_errors(true); $dom->loadXML($svgContent); libxml_clear_errors(); $svg = $dom->getElementsByTagName('svg')->item(0); // 初始化边界值 $minX = PHP_INT_MAX; $maxX = PHP_INT_MIN; $minY = PHP_INT_MAX; $maxY = PHP_INT_MIN; // 遍历所有圆形元素,计算边界 $circles = $dom->getElementsByTagName('circle'); foreach ($circles as $circle) { $cx = (float)$circle->getAttribute('cx'); $cy = (float)$circle->getAttribute('cy'); // 取动画中的最大半径值(你的示例中最大为4) $r = 4; // 更新全局边界 $minX = min($minX, $cx - $r); $maxX = max($maxX, $cx + $r); $minY = min($minY, $cy - $r); $maxY = max($maxY, $cy + $r); } // 计算新的viewBox参数 $viewBoxWidth = $maxX - $minX; $viewBoxHeight = $maxY - $minY; $newViewBox = sprintf("%.4f %.4f %.4f %.4f", $minX, $minY, $viewBoxWidth, $viewBoxHeight); // 更新SVG的viewBox属性 $svg->setAttribute('viewBox', $newViewBox); // 可选:将SVG宽高设置为包围盒实际大小,注释则保留原宽高 // $svg->setAttribute('width', $viewBoxWidth); // $svg->setAttribute('height', $viewBoxHeight); // 输出处理后的SVG,或保存到文件 echo $dom->saveXML(); // file_put_contents('trimmed-svg-file.svg', $dom->saveXML()); ?>
3. 扩展说明
- 如果SVG包含其他元素(如
rect、path),需要添加对应边界计算逻辑:- 矩形:用
x、y、width、height计算边界 - 路径:需要解析
d属性计算极值,可借助第三方库(如svg-php/svg)简化操作
- 矩形:用
- 如果有分组元素
<g>,需要递归遍历子元素确保不遗漏
内容的提问来源于stack exchange,提问作者Noah Thomson
相关产品推荐
相关产品推荐

