こんな方法があったのか！？ ビックリするくらい小さくなる SVG 画像の減量

みなさん！ イラストや絵をウェブページで使うとき、**SVG 画像、使っていますか？**

WebP や AVIF などの高圧縮率の画像フォーマットが主流になった今、むしろ **SVG だと余計にファイルサイズが大きくなってしまう**というケースもありがちなのではないでしょうか。せっかくベクタ画像で綺麗なイラストがあるのに、ファイルサイズ削減のため仕方なくラスタ画像として書き出す……なんてことも。

**ちょっと待ってください。その SVG 画像、もっと小さくできるかもしれませんよ？**

## SVG 画像のファイルを削減してみよう

ここで紹介するのは、[SVGO](https://github.com/svg/svgo) のような軽量化ツール**ではありません**。

今回は、Adobe illustrator を使用して、SVG 画像の減量に挑戦してみます。

## サンプル画像

![Adobe illustrator でサンプル画像を開いている画面。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/7b6b505e-d5cf-4400-a682-c2ca90d570db.png)

SVG 画像の減量がどのくらい効果があるのか試してみるために、今回はベクター画像で描かれたイラストを用意しました。これは僕のウェブサイトのコンテンツ [Android にちょっと詳しくなれるページ](https://aioilight.space/android-tips/)で使用しているキャラクターのイラストです。このイラスト自体は CLIP STUDIO PAINT のベクターレイヤーで描かれています。

## なにもしていない状態だと？

では、減量処理をする前に、そのまま illustrator から保存してどのくらいのファイルサイズがあるか確認してみます。今回は、名前を付けて保存から保存してみましょう。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/37916f64-748f-4908-8662-81893c6cc94b.png)

結果は、84.4 KB です。う～ん、微妙！ ちなみに、600 x 600 のロスレス WebP だと 81.1 KB になるため、200 CSSピクセルの横幅で表示するだけなら WebP の方がマシです。品質を落としても良いならもっと小さくできますし。

これをなんとかして SVG 画像でももっと小さくすることはできないでしょうか？

## 「シンボル」機能で似たオブジェクトをまとめる

何もしていない状態のサイズが分かったところで、減量作業をはじめていきましょう。一番改善幅が大きいのは、**「シンボル」機能を活用すること**です。

シンボル機能は、同じ形のグラフィックを、ひとつのシンボルとして登録して、使い回すことができる機能です。

サンプルのイラストで、同じ形の所を探してみましょう。特に分かりやすいところでいえば、「目」「手」「リボン」ですね。これは左右で反転しているものです。このイラストは左右対称のパーツが多いので、もっと同じ形の所はあるのですが、シンボルにすると効果が大きい 3 パーツを処理していきましょう。

![Adobe illustrator でシンボルを作成している画面。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/965bc75a-6cac-4fce-b9a3-faeb86911167.png)

シンボルの作成方法は簡単です、まずはシンボルにしたいオブジェクトを、ひとつのグループにまとめ、illustrator の「シンボル」パネルでシンボルを作成します。シンボルを作成する際、「ムービークリップ」か「グラフィック」か選択できますが、これはどちらもで違いがないとダイアログで説明されています (でもムービーではないのでなんとなくグラフィックを選択したくなりますね)。

OK を押せば、シンボルが出来上がります。この状態で、シンボルになったオブジェクトを、Alt + ドラッグなどで複製してみてください。複製された新しいオブジェクトは、**シンボルの "インスタンス"** になります。

![Adobe illustrator のシンボルパネルの画面。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/9aea113e-b57e-4bee-95fc-54e744b8fdb7.png)

シンボルが 3 つできました。これにより、**シンボルを複製しても、そのオブジェクトは「シンボルを参照している」という情報だけになるため、ファイルサイズが減ります。**

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/3df5f20f-b4e1-4200-b931-8f467ff0bc69.png)

74.2 KB になり、10.2 KB も減りました。

### ダイナミックシンボル・スタティックシンボルってなんだ？

illustrator の機能の説明になるため簡潔に説明しますが、ダイナミックシンボルでは、インスタンスに対して編集が効きます。例えば、シンボルがあり、複数そのシンボルのインスタンスがあって、「**インスタンス全ての形は同じだけど、色や線幅が違う**」というようなことができます。

逆に、そのようなことをしない場合は、スタティックシンボルで OK です。

## 「スクリーン用に書き出し」を使用してみる

実は、**illustrator から保存する時の保存方法の違いでも、ファイルサイズが変化する**のです。

![Adobe illustrator のスクリーン用に書き出しウィンドウ。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/1cb5ff03-f1f9-4549-a742-1d31505ec7e7.png)

illustrator には「直接ドキュメントを保存する」という方法に加え「スクリーン用に書き出し」という方法もあります。これは illustrator ドキュメントをラスタ画像として書き出す際に、解像度やフォーマットを自由に変更できるために作られたメニューですが、SVG 画像にでも使用することができます。

試しに、今シンボル化したデータを、「スクリーン用に書き出し」で書き出してみましょう。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/1c391e9f-3739-4901-9d75-29e8646781c5.png)

なんとこれだけでも 18 KB の差があります。なぜこちらの書き出し方法は、ファイルサイズが小さくなるのでしょうか？ illustrator は、通常の保存方法に加えてこのような処理をしています。

- ID やクラスメイトといったものをミニファイする
- 任意の小数点以下を丸める

これにより、ファイルサイズに差が付くんですね。試しに、テキストエディタで開いてみましょうか。

![ミニファイの前後をテキストエディタで比較している様子。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/e40b2abc-510f-48f3-a060-7a60357c474c.png)

一目瞭然ですね。

注意点があって、これは ID 名などもミニファイされるため、`svg` 要素として使用して、アニメーションなどをする場合はミニファイを避けた方が良いでしょう。再度 SVG を書き出すようなことがあれば、ID の指定も変更しないといけなくなってしまうからです (まあ、そんなに大変ではないか……)。

## パスの頂点数を減らす

クオリティを多少落としても良いのであれば、パスの数を減らすのがおすすめです。

このイラストデータはあらかじめ不要なパスが出ないように制作されているため、これ以上減らしても……という感じですがやってみましょう。オブジェクトを全選択した上で、オブジェクト→パス→単純化をやってみます。

![Adobe illustrator の単純化ウィンドウ。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/730c23a0-a3f3-461c-b2b6-9bb42b2ba7d0.png)

この画面が出ないときは歯車ボタンを押してください。変更前と後の頂点数を比較することができます。実際の仕上がり具合を見て、どのくらい頂点数を減らすか決めることができます。

繰り返しにはなりますがこのイラストはあらかじめ綺麗に作られているため、75 % に減らすだけでも形が崩れる箇所があります。今回はあくまでも例なので 85 % ほどでとりあえず単純化して、書き出してみます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/22db7ea5-057e-44b1-8329-6051e0949ad8.png)

結果 43.9 KB になりました。最初は 84.4 KB でしたので、**見た目を損なわずに、ほぼ半分のファイルサイズまで減量することができました**。

ちなみに、シンボルはこの方法で単純化することはできません。シンボルパネルからシンボルを編集するモードにしないと、操作できません (シンボルを作る前に単純化することをおすすめします)。

## 見えないところを消す

SVG には、ビューボックス (viewBox) があり、illustrator ではこれがそのままアートボードとして表現されます。SVG ではラスタ画像とは異なり、ビューボックスからはみ出してオブジェクトを存在させることが可能です。

実際にブラウザでレンダリングされるときは、ビューボックスの範囲内がビューポートにレンダリングされるため、ビューボックスの範囲外にあるオブジェクトを見ることはできません。

もちろん illustrator はアートボードの外にあるオブジェクトは自動的に「なかったこと」にしてくれるので、無駄なオブジェクトが入り込むことはないのですが、ビューボックスの "境界" に配置されたオブジェクトはどうなるかというと、**とくに処理されずそのまま SVG として書き出されてしまいます**。

つまり、**極端に頂点数が多いオブジェクトがビューボックスの境界にまたがっていると、かなり無駄になってしまう**ということです。

![血しぶきのようなエフェクトが付いているバナーのようなもの。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/dc88c464-a42d-4feb-8821-0c666a677d74.png)

例えば、このようなバナーを SVG で書き出すとすると、どうなるでしょうか。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/2a70e697-a7bd-4a0b-b64e-ec34894001ce.png)

33.9 KB ですね。

![書き出し後の画像を再度開いたところ。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/c5ce9db8-274e-4b8f-8a7b-a4bbfe04e661.png)

書き出した後の SVG をもう一度開いてみます。アートボードに被っていないオブジェクトは消えてくれていますが、ちょっとしか被っていないようなオブジェクトはそのまま残ってしまっています。

では、どうやって範囲外のパスを消すのかというと、パスファインダーを使えば簡単です。
 
まずは、適当な削る範囲を覆う長方形を作ります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/e1e9efe9-a8ce-4112-a999-439d63fc54a6.png)

あとはパスファインダーで「刈り込み」を選択すると、その範囲がカットされます。カットするオブジェクトが上に来ている必要があります。カットした後も四角形のオブジェクトは残るので、削除してください。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/28f17a44-d4b5-44d9-89d1-201d486313b6.png)

 33.9 KB から 29.3 KB まで減りました。ちょっとの作業量で画質を全く落とさずにできるので、はみ出しているオブジェクトが多いのであればやる価値があると思います。

## その他、気をつけたいこと

これは SVG の減量とは趣旨がズレるのですが、SVG 画像を書き出す前にチェックしてほしいことがあります。

それが「画像の埋め込まれミス」の防止です。例えば「参考画像」のような、制作中に illustrator 上に表示しておきたいもの があるとします。例えばそれが透過画像で、アートボードに対してその画像のバウンディングボックスが被さっているような状況だと、**事故が発生します**。 

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498509/752ad1cc-33cb-4d0d-bd13-5eb59b36b1e9.png)

このような場合に、そのまま SVG 画像を書き出すと、バウンディングボックスが被さっている画像も埋め込まれて書き出されてしまいます。ファイルサイズが爆上がりです。

まあこれは書き出し後のファイルサイズがおかしい数値になってしまうので、ほとんどの場合気づくと思います。**くれぐれも機密情報だったり権利的にマズいものが埋め込まれた状態でインターネット上に公開されないようにしたい**ですね……。

## まとめ

- **同じ形のオブジェクトはシンボルにする**
- 「**スクリーン用に書き出し**」を使用する
- **頂点数は見た目を損なわないレベルで減らす**
- **見えない範囲の複雑なオブジェクトは削る**

これさえ覚えていれば、もう立派な SVG 減量マスターですね！

----

https://aioilight.space/android-tips/

このキャラクターが使われているコンテンツを見てみたい……！ という方はこちらをどうぞ。

https://aioilight.space/web-corrects/svg-image-by-ai/

今回使用したテクニックなどは、こちらのページにも似たようなことが書かれています。