iMagick PHP从SVG转换为JPG

时间:2022-01-16 16:51:46

I am working in PHP and trying to use iMagick library to do an image conversion from SVG to JPG using shell_exec command. All seems to work, but the output JPG comes out very distorted. I almost get a feeling that the image is first converted and then resized.

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

I tried using "resize" and "scale" with same results.

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

Here is the command:

这是命令:

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

Any insights? Thanks in advance.

任何见解?提前致谢。

1 个解决方案

#1


0  

For anyone looking for a solution to this. Someone was able to come up with the following hack (with some of my edits):

对于任何寻找解决方案的人。有人能够提出以下黑客攻击(我的一些编辑):

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;
}

#1


0  

For anyone looking for a solution to this. Someone was able to come up with the following hack (with some of my edits):

对于任何寻找解决方案的人。有人能够提出以下黑客攻击(我的一些编辑):

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;
}