如何使用PHP调整SVG大小?

7

我正在尝试在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());

1
你可以使用PHP库contao/imagine-svg来调整和裁剪SVG图像。 - ausi
3个回答

10
考虑到“SVG”代表“可缩放矢量图形”。
  1. Imagick is a library for manipulating pixel-oriented grafics and as such unfit for vector grafic formats like SVG.

  2. SVGs are by their nature scalable. In most cases you will not need to rewrite them to change their size. If you display SVGs inside a webpage (via <img> or <object> tags, or as a CSS background-image, it will be displayed at the size defined for these elements, and if there is size information stored in the SVG file, that will be simply ignored. (Note that a lot of SVG files contain no display size information at all.)

  3. The only case you may need to set size information in the SVG file is if you display it as a standalone file (for example if you have a link pointing to the .svg itself).

    In this case, you can take advantage of the fact that SVG is a XML file:

    $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');
    

    There are some tricky cases if the element has no viewBox attribute and the width and height have non-px units. Handling them requires a deeper understanding of SVG. It would be best to assure that the SVG files produced by the "other script" always have a viewBox. Then the conditional section can be left out.

    The term "resolution" is inapplicable for vector grafics. Width and height can be dimensionless numbers (representing pixel for the purpose of rendering into an output device, for example the screen), or any valid CSS length unit: em, ex, px, pt, pc, cm, mm, in, and percentages.


1
Imagick使用视口在导入SVG到Imagick时生成基于像素的图像,因此,如果您需要比视口意味着更高的分辨率,则需要在缓存中读取SVG流,将viewBox大小参数更改为乘以值,然后再导入到Imagick中。或者您可以像您做的那样,这对我很有用... 我遇到了以下问题,导致出现空白图像:修复缺少的xml介绍。
if (substr($svgContent,0,5) != '<?xml') {
    $svgContent = '<?xml version="1.0" encoding="utf-8"?>' . $svgContent;
}

我犯的其他错误和可能无法正常工作的事情

  • 尝试导入无效的svg文件
  • 尝试根据以前的svg图像高度属性计算scaleImage的新高度值(毫无意义)
  • $bg->compositeImage($im, \Imagick::COMPOSITE_DEFAULT, $marginHorizontal, $marginVertical );中使用了与COMPOSITE_DEFAULT不同的东西,导致我导入的图像在我的情况下几乎看不见

-1

$view_box = implode(' ', [0, 0, $width[0], $height[0]]); //将此代码更改为 $view_box = implode(' ', [$your_width, $your_height, $width[0], $height[0]]);


目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接