web-dev-qa-db-ja.com

PHPを使用してSVG画像をPNGに変換します

私は、一連のデータに基づいてさまざまな州を着色する動的に生成された米国の地図を含むWebプロジェクトに取り組んでいます。

このSVGファイルを使用すると、米国の空のマップが得られ、各州の色を簡単に変更できます。困難なのは、IEブラウザーがSVGをサポートしていないため、svgが提供する便利な構文を使用するために、それをJPGに変換する必要があることです。

理想的には、Gd2ライブラリのみでこれを行いたいのですが、ImageMagickも使用できます。これを行う方法はまったくわかりません。

米国の地図上の州の色を動的に変更できるソリューションが検討されます。重要なのは、その場で色を簡単に変更できることと、クロスブラウザであることです。 PHP/Apacheソリューションのみ、お願いします。

102

あなたがこれを聞いたのは面白いです、私は最近私の仕事のサイトでこれをやったばかりで、チュートリアルを書くべきだと思っていました...ここにImageMagickを使用するPHP/Imagickでそれを行う方法があります:

$usmap = '/path/to/blank/us-map.svg';
$im = new Imagick();
$svg = file_get_contents($usmap);

/*loop to color each state as needed, something like*/ 
$idColorArray = array(
     "AL" => "339966"
    ,"AK" => "0099FF"
    ...
    ,"WI" => "FF4B00"
    ,"WY" => "A3609B"
);

foreach($idColorArray as $state => $color){
//Where $color is a RRGGBB hex value
    $svg = preg_replace(
         '/id="'.$state.'" style="fill:#([0-9a-f]{6})/'
        , 'id="'.$state.'" style="fill:#'.$color
        , $svg
    );
}

$im->readImageBlob($svg);

/*png settings*/
$im->setImageFormat("png24");
$im->resizeImage(720, 445, imagick::FILTER_LANCZOS, 1);  /*Optional, if you need to resize*/

/*jpeg*/
$im->setImageFormat("jpeg");
$im->adaptiveResizeImage(720, 445); /*Optional, if you need to resize*/

$im->writeImage('/path/to/colored/us-map.png');/*(or .jpg)*/
$im->clear();
$im->destroy();

正規表現の色置換の手順は、svgパスxmlおよびidと色の値の保存方法によって異なる場合があります。サーバーにファイルを保存したくない場合は、ベース64のように画像を出力できます

<?php echo '<img src="data:image/jpg;base64,' . base64_encode($im) . '"  />';?>

(clear/destroyを使用する前に)ただし、base64としてPNGに問題があるため、おそらくbase64をjpegとして出力する必要があります。

以前の雇用主の販売地域のマップに対して行った例をここで見ることができます。

開始: https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg

仕上げ: enter image description here

Edit

上記を書いて以来、私は2つの改善されたテクニックを思いつきました:

1)塗りつぶし状態を変更する正規表現ループの代わりに、CSSを使用して次のようなスタイルルールを作成します。

<style type="text/css">
#CA,#FL,HI{
    fill:blue;
}
#Al, #NY, #NM{
    fill:#cc6699;
}
/*etc..*/
</style>

そして、imagick jpeg/pngの作成に進む前に、単一のテキスト置換を実行してcssルールをsvgに挿入できます。色が変わらない場合は、CSSをオーバーライドするパスタグにインラインの塗りつぶしスタイルがないことを確認してください。

2)jpeg/png画像ファイルを実際に作成する必要がない場合(および古いブラウザをサポートする必要がない場合)、jQueryで直接svgを操作できます。 imgまたはobjectタグを使用してsvgを埋め込む場合、svgパスにアクセスできないため、次のようにsvg xmlをWebページhtmlに直接含める必要があります。

<div>
<?php echo file_get_contents('/path/to/blank/us-map.svg');?>
</div>

色の変更は次のように簡単です:

<script type="text/javascript" src="/path/to/jquery.js"></script>
<script type="text/javascript">
    $('#CA').css('fill', 'blue');
    $('#NY').css('fill', '#ff0000');
</script>
134
WebChemist

もう1つの非常に高速で正確なオプションは、ヘッドレスブラウザーPhantomJS(webkit)です。

http://phantomjs.org/

17
atomicjeep

IEはSVGをサポートしていないため、これを実行していると言います。

良いニュースは、IEdoesがベクターグラフィックスをサポートしていることです。わかりましたので、SVGではなくIEのみをサポートするVMLと呼ばれる言語の形式になっていますが、それはそこにあり、使用できます。

Googleマップなどは、ブラウザーの機能を検出して、SVGまたはVMLのどちらを提供するかを決定します。

次に、 Raphael library があります。これは、ブラウザに応じて、SVGまたはVMLのいずれかをサポートするJavascriptブラウザベースのグラフィックライブラリです。

役立つかもしれないもう一つ: SVGWeb

これらはすべて、ビットマップグラフィックスに頼らずにIEユーザーをサポートできることを意味します。

この質問に対するトップアンサーも参照してください。例: XSL Transform SVG to VML

11
Spudley

SVGを透明なPNGに変換するときは、$ imagick-> readImageBlob()の前にこのことを忘れないでください:

$imagick->setBackgroundColor(new ImagickPixel('transparent'));
8
psycho brm

これは非常に簡単です。過去数週間、この作業を行ってきました。

Batik SVG Toolkit が必要です。ダウンロードし、JPEGに変換するSVGと同じディレクトリにファイルを配置します。ま​​た、最初に解凍することも確認してください。

ターミナルを開き、次のコマンドを実行します。

Java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 NAME_OF_SVG_FILE.svg

これにより、SVGファイルのJPEGが出力されます。本当に簡単です。ループに配置して、SVGの負荷を変換することもできます。

import os

svgs = ('test1.svg', 'test2.svg', 'etc.svg') 
for svg in svgs:
    os.system('Java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 '+str(svg)+'.svg')
6
user179169

canvg jsライブラリを使用してSVGをPNGに変換できます。詳細はこちら http://paksula.users.cs.helsinki.fi/svg_open_2010/demo.xhtml すべての主要なブラウザと互換性があります!

私は私のプロジェクトでそれを使用しており、実際にSVGをPNGに変換します(もちろんファイルを保存するにはPHPの助けを借りて)

3
razor7

スタンドアロンのPHP/Apacheソリューションを知りません。これには、SVGイメージを読み取ってレンダリングできるPHPライブラリーが必要になるためです。そのようなライブラリが存在するかどうかはわかりません-知りません。

ImageMagick は、コマンドラインまたはPHPバインディングのいずれかを介してSVGファイルをラスタライズできます IMagick 示されているような依存関係in このフォーラムスレッド 。まだ最も有望な方法だと思います。もし私があなただったら最初に検討することです。

2
Pekka 웃

これは、標準のphp Gdツールを使用してsvg画像をgifに変換する方法です

1)ブラウザのキャンバス要素に画像を配置します:

<canvas id=myCanvas></canvas>

<script>
var Key='picturename'
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
base_image = new Image();
base_image.src = myimage.svg;
base_image.onload = function(){

    //get the image info as base64 text string

    var dataURL = canvas.toDataURL();
    //Post the image (dataURL) to the server using jQuery post method
    $.post('ProcessPicture.php',{'TheKey':Key,'image': dataURL ,'h': canvas.height,'w':canvas.width,"stemme":stemme } ,function(data,status){ alert(data+' '+status) });
}
</script>    

そして、サーバー(ProcessPicture.php)で(デフォルト)pngからgifに変換して保存します。 (pngとしても保存し、画像gifの代わりにimagepngを使用することもできます):

//receive the posted data in php
$pic=$_POST['image'];
$Key=$_POST['TheKey'];
$height=$_POST['h'];
$width=$_POST['w'];
$dir='../gif/'
$gifName=$dir.$Key.'.gif';
 $pngName=$dir.$Key.'.png';

//split the generated base64 string before the comma. to remove the 'data:image/png;base64, header  created by and get the image data
$data = explode(',', $pic);
$base64img = base64_decode($data[1]);
$dimg=imagecreatefromstring($base64img); 

//in order to avoid copying a black figure into a (default) black background you must create a white background

$im_out = ImageCreateTrueColor($width,$height);
$bgfill = imagecolorallocate( $im_out, 255, 255, 255 );
imagefill( $im_out, 0,0, $bgfill );

//Copy the uploaded picture in on the white background
ImageCopyResampled($im_out, $dimg ,0, 0, 0, 0, $width, $height,$width, $height);

//Make the gif and png file 
imagegif($im_out, $gifName);
imagepng($im_out, $pngName);
1
oleviolin