PerfectVector
著者: Irene Kim

p5.jsのSVG画像:読み込み、拡大縮小、元データの保管

p5.js 2.3.4で非同期setupを使ってSVGを読み込み、三つのCanvas表示サイズで透明な開口部を確認。編集可能なパスは表示画像と分けて保管します。

2 分で読める
目次

p5.js 2.3.4でSVG画像を読み込むには、async function setup()内でawait loadImage('emblem.svg')を使い、返された画像をimage()で描きます。ページとSVGはHTTPで配信してください。SVGファイルは編集可能なマスターとして残します。この画像読み込み経路はp5.ImageをCanvasに描くもので、スケッチに編集可能なSVGパスを渡すものではありません。現在のloadImageリファレンスに、Promiseベースの読み込みパターンが記載されています。

読み込みに成功しても、最初の問いに答えただけです。開口部が透明のままか、画像が引き伸ばされていないか、読み込んだピクセル寸法が最大の表示サイズに適しているかを確認してください。以下の例は、穴のある独自の角丸ひし形を使い、48、120、240ピクセルで描画します。

画像表示と元の形状のどちらが必要かを選ぶ

必要なこと保管または確認すること
既存のSVGイラストをp5のスケッチに描く画像として読み込み、Canvasの結果を確認する
イラストの元の輪郭を変える元のSVGファイルを別に保管し、編集する
画像を新しいサイズで描く縦横比を保ち、読み込んだ画像寸法を確認する
パスベースのSVGを書き出す別の形状処理またはSVG描画の手順を選び、検証する

このガイドはp5.js 2.3.4とP2Dレンダラーに固定しています。1.xのチュートリアルからpreload()のひな形をコピーするのではなく、現在の非同期APIを使います。createCanvasはスケッチのCanvasを作成し、レンダラーの明示的な選択に対応しています。

このバージョンの画像読み込み実装は、ブラウザーが読み込んだ画像を、p5.Imageの内部のCanvasへ描画します。そのため、.svgという拡張子を残してCanvasの表示を拡大するだけでは、スケッチ内のパスベースの編集は維持されません。

本物の開口部を持つ独自のSVGを保存する

このファイルをemblem.svgとして保存します。一つのパスがあり、埋め込みビットマップはなく、宣言したサイズは120 × 120で、一致するviewBoxを持ちます。外側の角丸ひし形と内側のひし形は、そのパス内の二つの輪郭です。fill-rule="evenodd"で中央を塗らずに残します。MDNのfill-ruleリファレンスで、この規則が塗り領域を決める仕組みを説明しています。

<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" viewBox="0 0 120 120">
  <path fill="#eb705a" fill-rule="evenodd" d="M60 8 Q66 8 72 14 L106 48 Q118 60 106 72 L72 106 Q60 118 48 106 L14 72 Q2 60 14 48 L48 14 Q54 8 60 8 Z M60 40 L80 60 L60 80 L40 60 Z"/>
</svg>

この開口部は、コーラル色の図形の上に白いひし形を置いたものではありません。スケッチの背景を変えるとき、この違いが重要です。既存のファイルに<image>要素が含まれる場合は、すべてのアートワークが編集可能なパスでできていると考える前に、埋め込みラスターのチェックリストで確認してください。

非同期setupで読み込む

次の完全なページをexample.htmlとしてemblem.svgの隣に保存し、そのフォルダーをローカルHTTPサーバーで配信します。たとえば、フォルダー内でpython3 -m http.server 8000を実行し、ブラウザーでhttp://localhost:8000/example.htmlを開きます。

<!doctype html>
<html lang="en"><meta charset="utf-8"><title>p5.js SVG image size check</title>
<p>Original 120 × 120 SVG; Canvas destinations 48, 120 and 240 pixels.</p>
<pre id="status">Loading original SVG…</pre>
<script src="https://cdn.jsdelivr.net/npm/p5@2.3.4/lib/p5.js"></script>
<script>async function setup() {
  createCanvas(650, 300, P2D);
  pixelDensity(1);
  noLoop();
  background('#e7eeea');
  try {
    const art = await loadImage('emblem.svg');
    for (const [x, size] of [[20, 48], [110, 120], [280, 240]]) {
      image(art, x, 20, size, size * art.height / art.width);
    }
    const center = art.get(60, 60);
    const solid = art.get(60, 25);
    document.querySelector('#status').textContent = JSON.stringify({
      version: p5.VERSION, imageWidth: art.width, imageHeight: art.height,
      sourceCenterRGBA: center, sourceSolidRGBA: solid,
      canvasWidth: width, canvasHeight: height, pixelDensity: pixelDensity(),
      destinationSizes: [48, 120, 240]
    }, null, 2);
  } catch (error) {
    document.querySelector('#status').textContent = 'Image load failed: ' + error.message;
  }
}</script></html>

ステータス欄は読み込み後に表示され、p5のバージョン、読み込んだ画像寸法、元画像の二つのピクセルサンプルを報告します。中央のサンプルは透明度を、コーラル色のサンプルはリングの不透明な部分を確認します。描画呼び出しは、一つの読み込んだ画像を共有しています。表示サイズの間でSVGを再読み込みしたり、変更したりしません。

imageリファレンスは、元の内容と出力先の幅、高さを区別しています。ここでは各出力先の高さをart.height / art.widthから計算するので、正方形でない画像に置き換えても比率を保てます。表示幅を変えるときも、この計算に両方の寸法を含めてください。

この例ではpixelDensity(1)を設定し、Canvasの比較条件を明確にしています。実際のスケッチが使う密度を記録してください。既定値はディスプレイに従う場合があります。Canvasの密度を上げても、すでに読み込み画像になったパスは再構築されません。

ブラウザーテストでわかったこと

元のファイルとこのひな形を、p5.js 2.3.4、P2D、ピクセル密度1を使ってChromeで実行しました。読み込んだ画像は120 × 120でした。中央のサンプルは[0, 0, 0, 0]で、内部のコーラル色のサンプルは[235, 112, 90, 255]でした。三つすべての出力先サイズで、薄い色のスケッチ背景が開口部を通して見えました。

Canvasの出力先読み込んだ画像との比率観察した結果
48 × 480.4×開口部の見える小さなリング
120 × 1201×読み込んだ寸法で表示される完全なリング
240 × 2402×リングと開口部は全体が見えるが、拡大した縁が明らかに柔らかい

これらの観察は、自作したこのファイル、このブラウザー、バージョン、レンダラーについてのものです。すべての書き出しSVG、フィルター、フォント、サードパーティーのランタイムに対する互換性の結果ではありません。

編集可能な元データとCanvas表示
輪郭付きの編集可能なコーラル色リングと、開口部から市松模様が見える三つの段階的に大きくなる画像表示の概念図。
模式図:元の輪郭と表示する画像は別々の役割を持ちます。この図はp5.jsのスクリーンショット、鮮明さの比較、変換結果ではありません。

テスト中、元のパスデータは変わりませんでした。画像を2×で描く操作が変えたのは表示であり、emblem.svgのd属性ではありません。後で別の納品用画像を準備できるよう、このマスターをプロジェクトとともに保存してください。

起きている症状を修正する

画像が表示されない

配信したページからSVGのURLにアクセスできることと、image()を実行する前にloadImage()が完了していることを確認します。ひな形のtry/catchは、読み込み失敗をステータス欄に表示します。loadImageの文書が指摘するように、リモート画像はブラウザーのセキュリティ制限で失敗することもあります。自分で管理する同一オリジンのファイルから始め、読み込みの問題とアートワークの問題を切り分けてください。

SVGだけをブラウザーで開きます。そこでも見た目が間違っているなら、まず元データを修正してください。名前を変えたPNGはSVGドキュメントにならず、ビットマップをSVGの入れ物に入れても不足した輪郭は作られません。

画像が引き伸ばされて見える

出力先の比率をart.width / art.heightと比較します。たとえば、正方形の画像を240 × 120の出力先に描くと、高さに対して幅を意図的に2倍にすることになります。引き伸ばす意図がないなら、ひな形の比率計算を使ってください。元画像自体に余分な余白がある場合は、表示を拡大して補う前に、アートボードとviewBoxを確認します。

拡大した縁がぼやける

Canvasのサイズだけでなく、読み込んだ画像寸法を確認します。このテストでは、120 × 120の画像を240 × 240の出力先に描きました。出力先の引数を変えても、新しい画像読み込みによってSVGの曲線が処理し直されるわけではありません。

用途に合う明示的な寸法の納品用SVGを準備し、再読み込みして、結果のart.widthとart.heightを確認してから採用してください。座標系と元の輪郭は維持します。その後、画面上の最小サイズと最大サイズを比較してください。読み込みピクセルを増やしても、最終表示が小さすぎる場合に小さな開口部を読み取れるようにはできません。

スケッチで画像の描画ではなく形状処理が必要な場合は、別に計画します。Canvas Path2Dガイドはパスデータの扱いを説明し、PixiJSのSVGガイドはそのエンジンの形状とテクスチャの経路を比較しています。これらのAPIは、p5のloadImage()と交換可能ではありません。

中央が透明ではなく白い

元のSVGに、塗られた背景や白い内側の図形がないか確認します。この元データでは、evenoddの輪郭が穴を残し、読み込んだ中央のアルファはゼロでした。自分のファイルでも、対照的な色のスケッチ背景の上で再確認してください。白いプレビューページでは違いが隠れる場合があります。

Canvasの書き出しとSVGマスターを分ける

標準のsaveCanvasリファレンスは、画像出力としてPNG、WebP、JPGを挙げています。そのAPIで描画済みCanvasを保存しても、元のSVGパスは復元されません。後から輪郭を編集したり、パスベースの納品ファイルが必要になったりする場合に備え、emblem.svgを別に保管してください。滑らかに見えるCanvasのスクリーンショットは、編集可能なSVGを書き出す手順の証拠にはなりません。

イラストがフラットなPNGやJPGでしか存在せず、編集するために元の輪郭が必要な場合は、上流の段階でPerfectVectorを使えます。画像をSVGに変換し、SVGエディターで輪郭と抜きの部分を確認してから、実際のp5での読み込みとサイズ確認を繰り返してください。きれいなSVGがすでにあるなら、そのまま使います。トレースはp5の画像APIを変えたり、Canvas出力をSVGパスドキュメントに変えたりするものではありません。より広いベクター化ガイドで、この元データ準備の段階を説明しています。

マスターを保管し、p5のバージョンと読み込んだ寸法を記録して、スケッチで使うサイズで開口部と縁が適切に見えることを確認してから、素材を採用してください。

よくある質問

p5.jsはloadImageでSVGを読み込めますか? はい。このp5.js 2.3.4 P2Dの例は、非同期setup内のawait loadImageで独自のSVGを読み込みます。一度読み込めたことを完全なSVG互換性と考えず、自分のファイルの見た目と読み込み寸法をテストしてください。

p5で読み込んだSVG画像はパスとして編集可能なままですか? 画像読み込みの経路はp5.Imageを返し、Canvasへ描きます。元のパスを編集するために、元のSVGを別に保管してください。Canvasの画像表示は、読み込んだアートワークの編集可能なSVG DOMを提供しません。

p5のSVGを拡大するとぼやけるのはなぜですか? 読み込んだ画像寸法と出力先の寸法を比較してください。この120 × 120の読み込み画像は、240 × 240ではより柔らかく見えました。適切なサイズの納品用元データを準備し、再読み込みして実際の結果を確認します。

saveCanvasは元のSVGを書き出しますか? 標準のsaveCanvas APIは、PNG、WebP、JPGの出力を文書化しています。元のSVGマスターを残すか、パスベースの出力には別のSVG描画と書き出し手順を検証してください。

出典

  1. p5.js loadImage — Promiseベースの画像読み込みとブラウザーの制限を説明しています。
  2. p5.js 2.3.4リリース — 固定バージョンと公式CDNスクリプトを示しています。
  3. p5.js createCanvas — Canvasの作成とレンダラー選択を説明しています。
  4. p5.js 2.3.4の画像読み込みソース — 読み込んだ画像をp5.Imageの内部Canvasへ描く処理を示しています。
  5. MDN fill-rule — evenoddが複合パスの塗り領域を決める仕組みを説明しています。
  6. p5.js image — 画像配置と出力先のサイズを定義しています。
  7. p5.js pixelDensity — スケッチのピクセル密度と、ディスプレイに依存する既定値を説明しています。
  8. p5.js saveCanvas — 標準のCanvas画像書き出し形式を挙げています。

ブログのその他の記事

PerfectVector

編集しやすい
よりきれいなSVGから始めましょう

クレジットカード不要