1

我正在使用 PHP 并尝试使用 iMagick 库使用 shell_exec 命令将图像从 SVG 转换为 JPG。一切似乎都有效,但输出的 JPG 非常失真。我几乎感觉到图像首先转换然后调整大小。

我尝试使用具有相同结果的“调整大小”和“缩放”。

这是命令:

"-resize 800x800 -quality 95 image.svg image.jpg"

有什么见解吗?提前致谢。

4

1 回答 1

0

对于任何正在寻找解决方案的人。有人能够想出以下技巧(通过我的一些编辑):

createThumbnail("input.svg", "output.jpg", 500, 500, $cdn_container);

function createThumbnail($filename, $thname, $width=100, $height=100, $cdn=null)
{
    try {
        $extension = substr($filename, (strrpos($filename, '.')) + 1 - strlen($filename));
        $fallback_save_path = "images/designs";

        if ($extension == "svg") {
            $im = new Imagick();
            $svgdata = file_get_contents($filename);
            $svgdata = svgScaleHack($svgdata, $width, $height);

            //$im->setBackgroundColor(new ImagickPixel('transparent'));
            $im->readImageBlob($svgdata);

            $im->setImageFormat("jpg");
            $im->resizeImage($width, $height, imagick::FILTER_LANCZOS, 1);

            $raw_data = $im->getImageBlob();

            (is_null($cdn)) ? file_put_contents($fallback_save_path . '/' . $thname, $im->getImageBlob()) : '';
        } else if ($extension == "jpg") {
            $im = new Imagick($filename);
            $im->stripImage();

            // Save as progressive JPEG
            $im->setInterlaceScheme(Imagick::INTERLACE_PLANE);
            $raw_data = $im->resizeImage($width, $height, imagick::FILTER_LANCZOS, 1);

            // Set quality
            // $im->setImageCompressionQuality(85);

            (is_null($cdn)) ? $im->writeImage($fallback_save_path . '/' . $thname) : '';
        }

        if (!is_null($cdn)) {
            $imageObject = $cdn->DataObject();
            $imageObject->SetData( $raw_data );
            $imageObject->name = $thname;
            $imageObject->content_type = 'image/jpg';
            $imageObject->Create();
        }

        $im->clear();
        $im->destroy();
        return true;
    }
    catch(Exception $e) {
        return false;
    }
}

function svgScaleHack($svg, $minWidth, $minHeight)
{
    $reW = '/(.*<svg[^>]* width=")([\d.]+px)(.*)/si';
    $reH = '/(.*<svg[^>]* 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;
}
于 2013-08-02T02:05:21.780 回答