【问题标题】:How to resize SVG with PHP?如何使用 PHP 调整 SVG 的大小?
【发布时间】:2018-07-27 00:17:31
【问题描述】:

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

【问题讨论】:

标签: php svg image-resizing imagick


【解决方案1】:

考虑一下“SVG”代表“Scalable Vector Grafics”。

  1. Imagick 是一个用于处理面向像素的图形的库,因此不适合 SVG 等矢量图形格式。

  2. SVG 本质上是可扩展的。在大多数情况下,您不需要重写它们来更改它们的大小。如果您在网页中显示 SVG(通过 <img><object> 标签,或作为 CSS background-image,它将以为这些元素定义的大小显示,并且如果 SVG 文件中存储了大小信息,这将被简单地忽略。(请注意,许多 SVG 文件根本不包含显示大小信息。)

  3. 您可能需要在 SVG 文件中设置大小信息的唯一情况是您将其显示为独立文件(例如,如果您有一个指向 .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 属性并且宽度和高度具有非像素单位,则会出现一些棘手的情况。处理它们需要对 SVG 有更深入的了解。最好确保“其他脚本”生成的 SVG 文件始终具有viewBox。那么条件部分就可以省略了。

    “分辨率”一词不适用于矢量图。宽度和高度可以是无量纲的数字(代表像素以用于渲染到输出设备,例如屏幕),或任何有效的 CSS 长度单位:em、ex、px、pt、pc、cm、mm、in 和百分比。

【讨论】:

    【解决方案2】:

    在将 svg 导入 imagick 时,Imagick 使用 viewbox 以 viewbox 的大小生成基于像素的图像。因此,如果您需要比 viewbox 更高的分辨率,则意味着您需要读取缓存中的 svg 流,将 viewBox 大小参数更改为相乘值,然后再导入 imagick。

    或者你可以完全按照你的做法。对我来说就像一个魅力......

    我遇到了以下导致空白图像的问题:

    修复缺少的 xml 介绍

    if (substr($svgContent,0,5) != '<?xml') {
        $svgContent = '<?xml version="1.0" encoding="utf-8"?>' . $svgContent;
    }
    

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

    • 尝试导入无效的 svg
    • 尝试根据以下公式计算 scaleImage 的新高度值 前 svg 图像高度属性(没有任何原因)
    • $bg-&gt;compositeImage($im, \Imagick::COMPOSITE_DEFAULT, $marginHorizontal, $marginVertical ); 中使用了与COMPOSITE_DEFAULT 不同的东西,这导致在我的情况下导入的图像几乎不可见

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2019-01-19
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      相关资源
      最近更新 更多