ElectronでCanvasの描画内容を画像ファイルとして保存できることを確認するためにサンプルアプリを作りました。
下記のような機能を実装しています。
- Canvasがマウスでドラッグされたら線を描く
- [クリア]ボタンが押されたらCanvasを背景色で塗りつぶす
- [ファイルに保存]ボタンが押されたらCanavsの描画内容を
~/Desktop/my-canvas.png
として保存する
描画内容の保存処理について
renderer.js
の下記の関数が画像ファイルの保存を行っています(36行目)。
function saveCanvas () {
const canvasDataUrl = myCanvas.toDataURL()
const decoded = dataUriToBuffer(canvasDataUrl)
fs.writeFile(imageFilePath, decoded, (err) => {
if (err) {
window.alert('ファイルの保存に失敗しました')
console.log(err)
} else {
window.alert('ファイルを保存しました')
}
})
}
myCanvas
変数には<canvas>
要素を含み、imageFilePath
変数には保存先の画像ファイルパスを含んでいて、下記が処理の流れです。
-
const canvasDataUrl = myCanvas.toDataURL()
で描画内容を画像データを含むData URIとして取得 -
const decode = dataUriToBuffer(canvasDataUrl)
取得したData URIをBuffer
に変換(npmモジュール data-uri-to-bufferを使用) -
fs.writeFile(...)
で保存
下記の情報を参考にさせていただきました。
- お絵描きアプリと画像の保存処理の実装 : アシアルブログ
- HTMLCanvasElement.toDataURL()
- Data URI scheme - Wikipedia
- data-uri-to-buffer
補足
サンプルアプリを作成する上で得られた、描画内容の保存以外の知見を記載しておきます。
タッチイベントとマウスイベントについて
サンプルアプリではマウスイベントのみ実装しているため、Microsoft Surfaceなどのタッチ入力が可能な端末では動作しないと思われます(手元に端末がないため実際にどうなるかは未確認です)。
下記の情報が参考になりそうでした。
- HTML5 の Canvas を使用して作成したゲームでユーザー入力を処理する
- Windows8のChromeやFirefoxはタッチイベントとマウスイベント両方考慮すべし - Webtech Walker
- タッチイベントとマウスイベントの両方を拾うマシン、ブラウザについて、マウス操作時にh5trackイベントが発火しない · Issue #298 · hifive/hifivemain
- マウス・タッチ・ペンのタッチ操作イベント
Canvasの描画について
<canvas>
要素のサイズをCSSで指定したことで、描画の位置や線の太さがずれてしまい、原因に気づくまでに時間がかかりました。下記の記事のおかげで気づきました。
また、<canvas>
要素の背景色をCSSで指定した場合、HTMLCanvasElement.toDataURL()
で取得したデータに背景色が含まれませんでした。あくまでもブラウザ上での背景色の指定として扱われ、Canvasの描画内容には含まれないようです。