底辺SE奮闘記

年収300万SEブログ

【PHP】meyfa/php-svg のススメ

PHPSVGを取り扱う際に便利なライブラリ「meyfa/php-svg」のご紹介です。

順次追記します

環境

下記の環境で試しております。

github.com

なお、gdは必須です。

インストール

composerで導入します。

composer require meyfa/php-svg

もちろん手動導入も可能です。詳しくは、上記githubから。

テキストを使用する場合は、gd以外にも

--with-freetype-dir=/usr

拡張設定が必要です。

phpenvの場合は、

(MAC)

$HOME/.phpenv/plugins/php-build/share/php-build/default_configure_options

に先ほどの拡張設定を追記して、

phpenv uninstall [PHPバージョン]
phpenv install [PHPバージョン]

としてPHPをインストールしなおすのが簡単で良いかと思います。

使用方法

オブジェクト生成

SVGオブジェクトは下記のようにSVGテキストから生成します。全ての始まりです。

<?php
use SVG\SVG;
$svg  = '<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500"></svg>';
$image = SVG::fromString($svg);

そのほか空のSVGオブジェクトを作成することも可能です。

ノードの追加

SVGオブジェクトに四角/円/テキストなどのノードを追加できます。

基本

ノードは概ね下記のように生成します。

<?php
$node = new SVGText('Hello World', 50, 50))
                   ->setFont($font)
                   ->setSize(40)
                   ->setStyle('fill', '#f00')

ノードのスタイルは、

<?php
$node->setStyle([スタイル名], [スタイル値]);

のように指定します。

主なスタイルは下記の通り、

スタイル名 スタイル値 概要
fill カラーコード(例:#FFFFFF) 塗りつぶし色
stroke カラーコード 枠線の色
stroke-width サイズ(例:2px) 枠線の太さ

直線

<?php
use SVG\Nodes\Shapes\SVGLine;
// $imageはSVGオブジェクト
$image->getDocument()->addChild(
    (new SVGLine(0, 0, 50, 50))
        ->setStyle('stroke', '#f00')
        ->setStyle('stroke-width', 5)
);

四角 矩形

<?php
use SVG\Nodes\Shapes\SVGRect;
// $imageはSVGオブジェクト
$image->getDocument()->addChild(
    (new SVGRect(0, 0, 50, 50))
        ->setStyle('fill', '#f00')
);

テキスト

フォントが必要になります。どこかから入手してきましょう。

<?php
use SVG\Nodes\Structures\SVGFont;
use SVG\Nodes\Texts\SVGText;
// $imageはSVGオブジェクト
$font = new SVGFont('IPAex明朝', "font/ipaexm.ttf");
$image->getDocument()->addChild($font);
$image->getDocument()->addChild(
    (new SVGText('Hello World', 50, 50))
        ->setFont($font)
        ->setSize(40)
        ->setStyle('fill', '#f00')
);

なお太字(font-weight:bold)には対応していないようです。

setStyle('stroke-width', '1px')などで無理やり対応できないこともない。

画像

<?php
use SVG\Nodes\Embedded\SVGImage;
// $imageはSVGオブジェクト
$image->getDocument()->addChild(
    new SVGImage("image.jpg", 0, 0, 50, 50)
);

SVG文字列の出力

SVGの中身を確認したい場合は下記の通り

<?php
// $imageはSVGオブジェクト
echo $image->toXMLString();

ラスタライズ

ラスタライズして画像に保存する場合は下記の通り。

<?php
// $imageはSVGオブジェクト
$rasterImage = $image->toRasterImage($w, $h);
imagepng($rasterImage, "test.png"));

円のアンチエイリアス

バージョン0.90現在、円にアンチエイリアスがかかっていません。

これはgdのimagefilledellipseがアンチエイリアスに対応していないためです。

meyfa/php-svgでは、SVGEllipseRenderer.phpの28行目の下記メソッドを書き換えることで、対応ができそうです。

<?php
//中略
protected function renderFill($image, array $params, $color)
{
    imagefilledellipse($image, $params['cx'], $params['cy'], $params['width'], $params['height'], $color);
}

ですが、それも手間なので楽をしたい場合は、画像にしてしまうか、テキストで●を書くといいと思います。

その他仕様

transformには未対応

下記のようなコードには対応していないようです。残念。

<svg>
<g transform="translate(100,100)">
~~~
</g>
</svg>