我正在向服务器发送一个SVG文件的字符串表示,并使用Imagick将其转换成jpeg,方式如下:
$image = stripslashes($_POST['json']); $filename = $_POST['filename']; $unique = time(); $im = new Imagick(); $im->readImageBlob($image); $im->setImageFormat("jpeg"); $im->writeImage('../photos/' . $type . '/humourised_' . $unique . $filename); $im->clear(); $im->destroy();
但是,我希望在光栅化SVG之前调整SVG的大小,以便生成的映像大于SVG文件中指定的维度.
$image = stripslashes($_POST['json']); $filename = $_POST['filename']; $unique = time(); $im = new Imagick(); $im->readImageBlob($image); $res = $im->getImageResolution(); $x_ratio = $res['x'] / $im->getImageWidth(); $y_ratio = $res['y'] / $im->getImageHeight(); $im->removeImage(); $im->setResolution($width_in_pixels * $x_ratio,$height_in_pixels * $y_ratio); $im->readImageBlob($image); $im->setImageFormat("jpeg"); $im->writeImage('../photos/' . $type . '/humourised_' . $unique . $filename); $im->clear(); $im->destroy();
该代码应该解决分辨率并相应地调整SVG的大小.如果SVG画布及其元素具有基于“百分比”的宽度,则它可以很好地工作,但是它似乎不适用于在“px”中定义的元素.不幸的是一个要求.
将发送到服务器的典型SVG字符串如下所示:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg id="tempsvg" style="overflow: hidden; position: relative;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="333" version="1.1" height="444"> <image transform="matrix(1,1,0)" preserveAspectRatio="none" x="0" y="0" width="333" height="444" xlink:href="http://www.songbanc.com/assets/embed/photos/full/133578615720079914224f9e7aad9ac871.jpg"></image> <image transform="matrix(1,0)" preserveAspectRatio="none" x="85.5" y="114" width="50" height="38" xlink:href="http://www.songbanc.com/assets/embed/humourise/elements/thumb/thumb_lips4.png"></image> <path transform="matrix(1,0)" fill="none" stroke="#000" d="M110.5,133L140.5,133" stroke-dasharray="- " opacity="0.5"></path> <circle transform="matrix(1,0)" cx="140.5" cy="133" r="5" fill="#000" stroke="#000"></circle> <path transform="matrix(1,133L110.5,155.8" stroke-dasharray="- " opacity="0.5"></path> <circle transform="matrix(1,0)" cx="110.5" cy="155.8" r="5" fill="#000" stroke="#000"></circle> <circle transform="matrix(1,0)" cx="110.5" cy="133" r="5" fill="#000" stroke="#000"></circle> </svg>
正如您可以看到构成该SVG的元素具有像素定义宽度和高度(使用百分比不幸不是此应用程序的选项)
有没有办法解决?或将SVG转换为png并将其呈现给定尺寸而不损失质量的任何其他方法.
谢谢.
编辑:虽然我从来没有设法找到一个完美的解决方案.相反,我结束发送SVG数据作为json,循环通过它的服务器端,并将像素缩放到预期的高度.
然后,经过多次尝试和错误,我意识到imagemagick在标准的SVG转换/旋转命令中出现问题,抛出任何操纵的元素.我结束了切换“inkscape”,将生成的SVG渲染为光栅图像.一切都很好.我还在挖掘一个潜在的配方解决方案,以抵消imagemagick造成的差异.如果我有成功,我会再次更新这个问题.
作为
php_imagick’s bug的解决方法,您可以缩放svg的width =“..”和height =“..”:
原文链接:https://www.f2er.com/php/132516.htmlfunction svgScaleHack($svg,$minWidth,$minHeight) { $reW = '/(.*<svg[^>]* width=")([\d.]+px)(.*)/si'; $reH = '/(.*<svg[^>]* height=")([\d.]+px)(.*)/si'; preg_match($reW,$svg,$mw); preg_match($reH,$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; }
然后你可以轻松创建漂亮的透明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,imagick::FILTER_LANCZOS,1); file_put_contents($thname,$im->getImageBlob()); $im->clear(); $im->destroy(); }
注意:
我一直在寻找一个解决方案如何从最初的小尺寸重新调整SVG.然而,似乎imagick :: setResolution是破碎的.但是,ImageMagick库本身正在运行,所以您可以使用exec(‘convert …’)(由于托管提供商的安全原因,可能会被禁用).
所以要从较小的svg创建缩略图50×50你会做:
convert -density 500 -resize 50 50 -background transparent a.svg PNG32:a.png