如何使用 PHP 调整 SVG 的大小?
How to resize SVG with PHP?
我正在尝试在 PHP 脚本中调整(增加大小)SVG 并将其另存为新的 SVG。给定的 SVG 是由另一个脚本生成的。它包含图像和文本。
我试过 imagick
,但生成的 svg 已损坏,并且不包含任何内容。
我是这样做的:
$image = new Imagick();
$image->setResolution(2000,2000);
$image->readImage('/pathe/to/my/svg.svg');
$image->scaleImage(1000,1000);
file_put_contents('/pathe/to/my/new.svg', $image->getImageBlob());
考虑 "SVG" 代表 "Scalable Vector Grafics"。
Imagick 是一个用于处理 pixel-oriented 图形的库,因此不适合像 SVG 这样的矢量图形格式。
SVG 本质上是可扩展的。在大多数情况下,您不需要重写它们来改变它们的大小。如果您在网页内显示 SVG(通过 <img>
或 <object>
标签,或作为 CSS background-image
,它将以为这些元素定义的大小显示,如果SVG 文件中存储了尺寸信息,这些信息将被忽略。(请注意,很多 SVG 文件根本不包含显示尺寸信息。)
您可能需要在 SVG 文件中设置大小信息的唯一情况是将其显示为独立文件(例如,如果您有 link 指向 .svg本身)。
在这种情况下,您可以利用 SVG 是 XML 文件这一事实:
$dom = new DOMDocument('1.0', 'utf-8');
$dom->load('/pathe/to/my/svg.svg');
$svg = $dom->documentElement;
if ( ! $svg->hasAttribute('viewBox') ) { // viewBox is needed to establish
// userspace coordinates
$pattern = '/^(\d*\.\d+|\d+)(px)?$/'; // positive number, px unit optional
$interpretable = preg_match( $pattern, $svg->getAttribute('width'), $width ) &&
preg_match( $pattern, $svg->getAttribute('height'), $height );
if ( $interpretable ) {
$view_box = implode(' ', [0, 0, $width[0], $height[0]]);
$svg->setAttribute('viewBox', $view_box);
} else { // this gets sticky
throw new Exception("viewBox is dependent on environment");
}
}
$svg->setAttribute('width', '1000');
$svg->setAttribute('height', '1000');
$dom->save('/pathe/to/my/new.svg');
如果元素没有 viewBox
属性并且宽度和高度有 non-px 单位,则会出现一些棘手的情况。处理它们需要对 SVG 有更深入的了解。最好确保 "other script" 生成的 SVG 文件始终具有 viewBox
。那么条件部分可以省略。
术语"resolution"不适用于矢量图。宽度和高度可以是无量纲数(代表像素以呈现到输出设备,例如屏幕),或任何有效的 CSS 长度单位:em、ex、px、pt、pc、cm、mm 、in 和百分比。
Imagick 在将 svg 导入 imagick 时使用视框生成视框大小的基于像素的图像。因此,如果您需要比 viewbox 更高的分辨率,则意味着您需要读取缓存中的 svg 流,将 viewBox 大小参数更改为相乘的值,然后仅导入到 imagick 中。
或者你也可以完全按照你所做的去做。对我来说就像一个魅力...
我遇到了导致空白图像的以下问题:
修复缺失的xml简介
if (substr($svgContent,0,5) != '<?xml') {
$svgContent = '<?xml version="1.0" encoding="utf-8"?>' . $svgContent;
}
我犯的其他错误以及可能无法正常工作的东西
- 尝试导入无效的 svg
- 尝试计算
scaleImage
的新高度值基于
以前的 svg 图像高度属性(没有任何意义)
- 在
$bg->compositeImage($im, \Imagick::COMPOSITE_DEFAULT, $marginHorizontal, $marginVertical );
中使用了与 COMPOSITE_DEFAULT
不同的东西,这导致导入的图像在我的情况下几乎不可见
$view_box = 内爆(' ', [0, 0, $width[0], $height[0]]); //将此代码更改为 $view_box = implode(' ', [$your_width, $your_height, $width[0], $height[0]]);
我正在尝试在 PHP 脚本中调整(增加大小)SVG 并将其另存为新的 SVG。给定的 SVG 是由另一个脚本生成的。它包含图像和文本。
我试过 imagick
,但生成的 svg 已损坏,并且不包含任何内容。
我是这样做的:
$image = new Imagick();
$image->setResolution(2000,2000);
$image->readImage('/pathe/to/my/svg.svg');
$image->scaleImage(1000,1000);
file_put_contents('/pathe/to/my/new.svg', $image->getImageBlob());
考虑 "SVG" 代表 "Scalable Vector Grafics"。
Imagick 是一个用于处理 pixel-oriented 图形的库,因此不适合像 SVG 这样的矢量图形格式。
SVG 本质上是可扩展的。在大多数情况下,您不需要重写它们来改变它们的大小。如果您在网页内显示 SVG(通过
<img>
或<object>
标签,或作为 CSSbackground-image
,它将以为这些元素定义的大小显示,如果SVG 文件中存储了尺寸信息,这些信息将被忽略。(请注意,很多 SVG 文件根本不包含显示尺寸信息。)您可能需要在 SVG 文件中设置大小信息的唯一情况是将其显示为独立文件(例如,如果您有 link 指向 .svg本身)。
在这种情况下,您可以利用 SVG 是 XML 文件这一事实:
$dom = new DOMDocument('1.0', 'utf-8'); $dom->load('/pathe/to/my/svg.svg'); $svg = $dom->documentElement; if ( ! $svg->hasAttribute('viewBox') ) { // viewBox is needed to establish // userspace coordinates $pattern = '/^(\d*\.\d+|\d+)(px)?$/'; // positive number, px unit optional $interpretable = preg_match( $pattern, $svg->getAttribute('width'), $width ) && preg_match( $pattern, $svg->getAttribute('height'), $height ); if ( $interpretable ) { $view_box = implode(' ', [0, 0, $width[0], $height[0]]); $svg->setAttribute('viewBox', $view_box); } else { // this gets sticky throw new Exception("viewBox is dependent on environment"); } } $svg->setAttribute('width', '1000'); $svg->setAttribute('height', '1000'); $dom->save('/pathe/to/my/new.svg');
如果元素没有
viewBox
属性并且宽度和高度有 non-px 单位,则会出现一些棘手的情况。处理它们需要对 SVG 有更深入的了解。最好确保 "other script" 生成的 SVG 文件始终具有viewBox
。那么条件部分可以省略。术语"resolution"不适用于矢量图。宽度和高度可以是无量纲数(代表像素以呈现到输出设备,例如屏幕),或任何有效的 CSS 长度单位:em、ex、px、pt、pc、cm、mm 、in 和百分比。
Imagick 在将 svg 导入 imagick 时使用视框生成视框大小的基于像素的图像。因此,如果您需要比 viewbox 更高的分辨率,则意味着您需要读取缓存中的 svg 流,将 viewBox 大小参数更改为相乘的值,然后仅导入到 imagick 中。
或者你也可以完全按照你所做的去做。对我来说就像一个魅力...
我遇到了导致空白图像的以下问题:
修复缺失的xml简介
if (substr($svgContent,0,5) != '<?xml') {
$svgContent = '<?xml version="1.0" encoding="utf-8"?>' . $svgContent;
}
我犯的其他错误以及可能无法正常工作的东西
- 尝试导入无效的 svg
- 尝试计算
scaleImage
的新高度值基于 以前的 svg 图像高度属性(没有任何意义) - 在
$bg->compositeImage($im, \Imagick::COMPOSITE_DEFAULT, $marginHorizontal, $marginVertical );
中使用了与COMPOSITE_DEFAULT
不同的东西,这导致导入的图像在我的情况下几乎不可见
$view_box = 内爆(' ', [0, 0, $width[0], $height[0]]); //将此代码更改为 $view_box = implode(' ', [$your_width, $your_height, $width[0], $height[0]]);