今までSVGファイルをプログラムで出力するときはimg
タグにサイズは書かず、CSSで横幅だけ指定して大きさを調整していました。ですがGoogleの掲げるCLS対策でimg
タグにはwidth
とheight
属性を設定した方がよい、ということになって話が変わってきました。
PHPではgetimagesize()
を使えばPNGやJPEGのようなビットマップ画像のサイズは簡単に取得できますが、残念ながらSVGには対応していません。
縦横のサイズ(または縦横比)が分からないと、width
とheight
を正しく指定できないのでCLS対策ができません。
「これは困った!」ということでいろいろ調べて見つけたSVGの幅と高さを取得する方法をご紹介します。
SVGの大きさはどうやって決まる?
そもそもSVGはベクターデータなので絶対的な大きさはありません。しかし、大きさを指定する属性は持っています。それを使えば良いのですが、使うSVGがどのようにサイズを指定しているかを調べる必要があります。ここではそれを3つに分類しています。
width
・hegiht
属性を持っているviewBox
属性のみ持っているwidth
・height
・viewBox
属性を持っていない
それぞれで大きさを取得する方法が変わってきます。
width
・height
属性を持っている場合
SVGがwidth
・height
属性を持っている場合、SVGファイルをXMLファイルとして読み込み、width
とheight
属性を取り出します。コードは次のようになります。
<?php
$svg_xml = simplexml_load_string($img_url);
$xml_attributes = $svg_xml->attributes();
$width = (string) $xml_attributes->width;
$height = (string) $xml_attributes->height;
?>
<img src="<?php echo $img_url; ?>" width="<?php echo $width; ?>" height="<?php echo $height; ?>" >
simplexml_load_string()
はXMLファイルを読み込んでPHPオブジェクトにしてくれます。そこから幅と高さのデータを取り出しています。
この例ではそのままimg
タグに使っていますが、もしデフォルトのサイズから拡大・縮小している場合はそれに合わせて$width
と$height
を計算しなおしましょう。
viewBox
属性のみ持っている場合
次はwidth
とheight
属性を持たずviewBox
が指定されている場合です。私がよく使うAffinity Designerで出力したSVGはこのタイプでした。illustratorではwidth
とheight
属性があるようです。
<?php
$svg_xml = simplexml_load_file($img_url);
list($originX, $originY, $relWidth, $relHeight) = explode(' ', $svg_xml['viewBox']);
$width=300; // 指定したい画像の幅
$height = $width * $relHeight / $relWidth;
?>
<img src="<?php echo $img_url; ?>" width="<?php echo $width; ?>" height="<?php echo $height; ?>" >
先ほどと同じくSVGファイルをXMLとして読み込んでからviewBox
属性を取り出します。
viewBox
属性には<svg viewBox="0 0 218 52">
のようにスペース区切りで4つの数字が設定されています。このコードでは
explode()
を使ってスペース区切りで分割list()
を使って各変数に代入
として各数値を取得しています。
viewBox
属性の4つの数字のうち、後ろの2つが画像の幅と高さになります。
上記のソースではここで取得した幅と高さを使って300px幅に合わせた高さを計算しています。このように縦か横のどちらかが決まればサイズを指定することができます。
厳密にいうと、上記の方法では画像の実際の大きさを取得できない可能性があります。viewBoxで取得できるサイズは画像の大きさではなく画像の描画エリアのサイズだからです。
通常は画像がピッタリ収まるサイズのviewBox
になっていることがほとんどだと思いますが、もし画像より大きめのviewBox
が設定されていた場合(余白が大きい画像と同じ)、意図しないサイズになる可能性があります。
その場合はviewBox
の値を調整する必要があるかもしれません。
width
・height
・viewBox
属性を持っていない
私はこういうファイルに今までお目にかかったことはないですが、この場合は簡単にサイズを取得することができません。画像の頂点を全て取得して最大値を探せばサイズを計算できそうですがプログラムを組むのは大変そうです。
探せばサイズを計算するライブラリとかありそうですが、Affinity Designのようなグラフィックソフトで保存し直すのが手っ取り早いと思います。そういうソフトがない場合は、
- ChromeなどのWebブラウザでサイズ指定なしで表示
- デベロッパーツールで大きさを確認
- その数値をSVGファイルに書き込む
という流れで修正すれば対応できそうです。
いかがだったでしょうか?
今回、この記事のためにSVGのことを結構しらべましたが、なかなか奥が深いですね。Web画像として使うならviewBox
だけを指定がベストなことは分かりました。
ちなみにAffinity Designer ではSVGの書き出し設定の中に「viewBoxを設定する」というオプションがありました。Webで使うならこの設定にチェックは必須ですね。
- この記事のコードは下記サイトのものを参考にさせてもらいました。
How do you get the width and height of an SVG picture in PHP? – Stack Overflow
viewBox
については下記のページを見るとイメージしやすくなると思います。
SVGのviewBoxをわかりやすく紐解く|NEWS|株式会社INDETAIL(インディテール)- viewBoxの指定についてもっと深く知りたい場合は下記の記事が参考になります。
【SVG】SVGのwidth・height属性はどう考えるとしっくりくる? | LUCKLOG viewBox
とwidth
・height
の指定のどちらが使い勝手が良いかについてはこの記事に詳しいです。基本はviewBox
のみの方が良さそうですね。
viewBox属性でSVGをレスポンシブ対応させる | Free Style
コメント
この記事へのコメントはありません。