「Canvasって何・・・?」状態のオンナが、Canvasを使ってsvgをpng画像に変換・ダウンロードするまで

Canvas
※当ブログの記事内にはプロモーションが含まれている場合があります。

何度もお目にかかっていたCanvasさん。
避けに避け続けていましたが、業務で使わざるを得ない状況になったので、
お勉強と実装をしてみました。

最終的に、Vue3で、svgをpngにしたい

※svgは、インラインで直接表示させているもの。

最初、参考サイトの通りに実装しましたが、
svgの読み込みが上手く行いかなかった&エラーがあったので、
不具合・エラーを直したものを、こちらに残しておきます・・・。

Canvasとは

  • HTML5とJavaScript(以下、JS)でブラウザ上に図が描けるもの
  • <canvas>タグにJSで、図を描画していく
  • Canvasでレイアウトを決めた部分には、CSSでレイアウトを適用できない

SVGのPNG画像変換

大まかな流れとしては、CanvasとJSを使って、svgをPNG画像に変換・描画し、PNG画像のデータをダウンロード。

手順

  1. XMLSerializerを使って、SVG画像のデータを取り出す
  2. CanvasとJSを使って、PNG形式に変換
  3. CanvasのtoDataURL()で、PNG画像のURIを取得
  4. ローカルにpng画像をダウンロード

コード

// vue
<div @click="download()">
    <svg id="sample">....いろいろ描いてあります.....</svg>
</div>
const download = () => {
      // svg domを取得
      const svg = document.getElementById('sample')

      // canvasを準備
      let canvas = document.createElement('canvas')
      canvas.width = svg.width.baseVal.value
      canvas.height = svg.height.baseVal.value

      // 描画をするための、canvasの組み込みオブジェクトを準備
      const ctx = canvas.getContext('2d')
      // imgオブジェクトを準備
      let image = new Image()

      // imageの読み込みが完了したら、onloadが走る
      image.onload = () => {
        // SVGデータをPNG形式に変換する
        // canvasに描画する drawImage(image, x座標, y座標, 幅, 高さ)
        ctx.drawImage(image, 0, 0, image.width, image.height)

        // ローカルにダウンロード
        let link = document.createElement("a")
        link.href = canvas.toDataURL() // 描画した画像のURIを返す data:image/png;base64
        link.download = "canvas.png"
	link.click()
      }
      // 読み込みに失敗したらこっちが走る
      image.onerror = (error) => {
        console.log(error)
      }

      // SVGデータをXMLで取り出す
      const svgData = new XMLSerializer().serializeToString(svg)
      // この時点で、上記のonloadが走る
      image.src = 'data:image/svg+xml;charset=utf-8;base64,' + btoa(unescape(encodeURIComponent(svgData)))
}

コード解説

canvas.getContext(“2d”)

getContext(“2d”) オブジェクトは、線、ボックス、円、などを描画するメソッドを持っています。

http://memopad.bitter.jp/w3c/html5/html5_ref_canvas.html

使える描画メソッド一覧も、上記のサイトにあります。

例えば、drawImage()メソッドは、canvasに画像を描画する。

const image = new Image()
const ctx = canvas.getContext('2d')
ctx.drawImage(image, x座標, y座標, 幅, 高さ)

new Image()

The Image() constructor creates and returns a new HTMLImageElement object representing an HTML <img> element which is not attached to any DOM tree. It accepts optional width and height parameters. When called without parameters, new Image() is equivalent to calling document.createElement(“img”).

https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement

新しいHTMLImageElementインスタンス(<img>)を作成するコンストラクタ
つまり、new Image()をすることで、imgタグを作成できる

image.onload

image.srcに画像のパスを渡して、読み込み完了したタイミングで、onloadが走る

drawImage

drawImageは、<canvas>へ画像を描画する。

serializeToString

XMLSerializerのメソッドで、HTMLElementオブジェクトを、XML出力する。

new XMLSerializer().serializeToString(HTMLElementオブジェクト)
Window: btoa() メソッド - Web API | MDN
btoa() は Window インターフェイスのメソッドで、 Base64 でエンコードされた ASCII 文字列をバイナリー文字列(すなわち、文字列のそれぞれの文字がバイナリーデータの各バイトとして扱われる文字列)から生成します。

btoa

  • WindowOrWorkerGlobalScope.btoa()メソッドは、バイナリ文字列から、Base64でエンコードされたASCII文字列を生成する。
  • 使いどころ:画像のデータを文字列でsrcに渡したいときなど
    • btoaでデータをエンコードしている
    • atobで再度デコードできる

toDataURL

  • canvasのメソッド
  • 画像の data URI を返す。
  • typeパラメーターで、画像ファイルの形式を指定できる(デフォルトはpng)
  • 返り値の例:data:image/png;base64,iVBORw0KGgoAAAANSUhE……

用語

SVG

  • スケーラブル・ベクター・グラフィックス、Scalable Vector Graphics
  • 画像形式の1つ
  • XMLをベースにしたベクターデータで画像を描画(拡大・縮小しても画質が損なわれない)
  • イラレ以外にも、d3jsというもので作成できるらしい

XMLSerializer

XMLSerializer インターフェースは、DOM ツリーを表す XML 文字列を構築するための serializeToString() (en-US) メソッドを提供します。

https://developer.mozilla.org/ja/docs/Web/API/XMLSerializer

  • DOMから、XML文字列を生成するためのクラス
  • 最新のブラウザならだいたい対応している(チェック
  • new XMLSerializer() オブジェクトを使用する

参考サイト

お世話になりました・・・(愛)

知っておきたいHTMLのCanvasとは?何ができるのかを解説 | 侍エンジニアブログ
この記事では「 知っておきたいHTMLのCanvasとは?何ができるのかを解説 」といった内容について、誰でも理解できるように解説します。この記事を読めば、あなたの悩みが解決するだけじゃなく、新たな気付きも発見できることでしょう。お悩みの方...
SVGを画像化する
はじめに 昨今のクライアントサイドでは、動的な画像のレンダリング、アニメーション、拡張・縮小を求められることが多々あります。そのような際にSVGは利用しやすい形式です。一方で、画像として内容を保存したくなることもあります。そのような場合に使...
XMLSerializer - Web API | MDN
XMLSerializer インターフェイスは serializeToString() メソッドを提供します。これにより、 DOM ツリーを表す XML 文字列を構築することができます。
JavaScriptプログラミング講座【DOMParser について】
HTML5 canvas.getContext("2d") reference
Free HTML XHTML CSS JavaScript DHTML XML DOM XSL XSLT RSS AJAX html ADO PHP SQL tutorials, references, examples for web ...
画像の使用 - Web API | MDN
これまで、図形を作成してスタイルを適用する方法を見てきました。 のより面白い機能のひとつが、画像を扱えることです。これは動的な画像合成を行う、グラフの背景として使用する、ゲームのスプライトとして使用するなどといったことが可能です。 PNG、...
HTMLImageElement - Web APIs | MDN
The HTMLImageElement interface represents an HTML element, providing the properties and methods used to manipulate image...
HTMLImageElement: Image() constructor - Web APIs | MDN
The Image() constructor creates a new HTMLImageElement instance. It is functionally equivalent to document.createElement...
PromiseベースでImage().onloadする - Qiita
#やりたいことJavaScriptで、画像の width/height が知りたいとき、以下のようにする。const img = new Image();img.onload = () => …
HTML5 canvas drawImage Method
Free HTML XHTML CSS JavaScript DHTML XML DOM XSL XSLT RSS AJAX html ADO PHP SQL tutorials, references, examples for web ...
SVGを画像に変換してダウンロードする方法 - Qiita
D3.jsやflowchart.jsなど、SVGで出力された画像を保存したくなるときが多々あります。そんなときに使うjavascript。Chromeのデバッガーツールのconsoleから入力する…
Window: btoa() メソッド - Web API | MDN
btoa() は Window インターフェイスのメソッドで、 Base64 でエンコードされた ASCII 文字列をバイナリー文字列(すなわち、文字列のそれぞれの文字がバイナリーデータの各バイトとして扱われる文字列)から生成します。
Canvasで画像をダウンロードしたい|yusaku
canvasで作ったら、当然ダウンロードしたいですよね。 ブログのトップ画像に使ったり、SNSで「こんなの作りました」と言っといたほうがいい時代ですし。 canvasでダウンロードってどうするんだろう?と調べてみたのですが、すぐにわからなか...
HTML5でのSVGファイル操作のおさらい - Qiita
最近、HTML5でベクターグラフィックスを取り扱う時にSVG形式のファイルを利用しているWEBサイトが増えて来ている。iOS系のデバイスが超高解像度のRetinaディスプレイを採用しているので、PC…
画像ファイルをバイナリではなくテキストで扱うbase64フォーマットって便利なのだろうか?
ITエンジニア,技術学習,アイデア,妄想日記,メンタルコントロール,継続ブログ,Podcast,プログラミング

 

コメント

タイトルとURLをコピーしました