how to resize an SVG with Imagick/ImageMagick

后端 未结 4 699

I am sending a string representation of an SVG file to the server and using Imagick to turn this into a jpeg in the following manner:

$image = stripslashes($         


        
4条回答
  •  梦毁少年i
    2020-12-29 10:51

    As a workaround of php_imagick's bug, you can scale svg's width=".." and height="..":

    function svgScaleHack($svg, $minWidth, $minHeight)
    {
        $reW = '/(.*]* width=")([\d.]+px)(.*)/si';
        $reH = '/(.*]* height=")([\d.]+px)(.*)/si';
        preg_match($reW, $svg, $mw);
        preg_match($reH, $svg, $mh);
        $width = floatval($mw[2]);
        $height = floatval($mh[2]);
        if (!$width || !$height) return false;
    
        // scale to make width and height big enough
        $scale = 1;
        if ($width < $minWidth)
            $scale = $minWidth/$width;
        if ($height < $minHeight)
            $scale = max($scale, ($minHeight/$height));
    
        $width *= $scale*2;
        $height *= $scale*2;
    
        $svg = preg_replace($reW, "\${1}{$width}px\${3}", $svg);
        $svg = preg_replace($reH, "\${1}{$height}px\${3}", $svg);
    
        return $svg;
    }
    

    Then you can easily create nice transparent PNG!

    createThumbnail('a.svg', 'a.png');
    
    function createThumbnail($filename, $thname, $size=50)
    {
        $im = new Imagick();
        $svgdata = file_get_contents($filename);
        $svgdata = svgScaleHack($svgdata, $size, $size);
    
        $im->setBackgroundColor(new ImagickPixel('transparent'));
        $im->readImageBlob($svgdata);
    
        $im->setImageFormat("png32");
        $im->resizeImage($size, $size, imagick::FILTER_LANCZOS, 1);
    
        file_put_contents($thname, $im->getImageBlob());
        $im->clear();
        $im->destroy();
    }
    

    Note: I've been searching for a solution how to rescale SVG from its initial small size. However it seems that imagick::setResolution is broken. However, ImageMagick library itself is working, so you can use exec('convert...') (might be disabled for security reasons by hosting provider).

    So to create thumbnail 50x50 from smaller svg you would do:

    convert -density 500 -resize 50 50 -background transparent a.svg PNG32:a.png
    

提交回复
热议问题