白ハゲ４コマメーカーのデスクトップ化に伴う画像保存ダイアログの追加


# 白ハゲ４コマメーカーとは

[白ハゲ４コマメーカー(正式名称mangadown)](https://anydown.github.io/mangadown/)は

>Twitterで
よく流れている
タイプの４コマを
作るツール

です。閲覧はChrome推奨。

ちなみにFirefoxだと文字が90度時計回りになってしまうので、ソースの方で

```javascript:bundle.js
 function tategaki(ctx, text, x, y, px) {
  ctx.fillStyle = ""
  ctx.font = px + "px 'newfont'";
  for (var i = 0; i < text.length; i++) {
    ctx.save();
    ctx.translate(x, y + px * i);
    //ctx.rotate(Math.PI / 2);
    ctx.translate(2, -px - 3);
    ctx.fillText(text[i], 0, px);
    ctx.restore();
  }
}
```

のようにコメントアウトするなどの応急処置が必要みたいです。


# 改造内容

## Electronによるデスクトップ化

基本、[ソース](https://github.com/anydown/mangadown)を取ってきて、electron-packagerするだけです。

が、画像保存は window.open() されているだけなのでちょっと不便です。

## Electronでの画像保存その１

Electronから画像を保存する方法は、

[ElectronでCanvasの描画内容を画像ファイルとして保存する](http://qiita.com/jakalada/items/6f62b2089a67a04514b7)

で紹介されていますが、今のElectron(v1.6.11)だと動かないので[ソース](https://github.com/jakalada/example-electron-paint-and-save-file)は１箇所だけ

```javascript:renderer.js
//const remote = require('remote')
const remote = require('electron').remote
```

のように修正する必要があります。

## Electronでの画像保存その２

あと、どうせ保存するならダイアログが欲しいよね？ということで、

[続・Electronでファイルやフォルダの選択(保存もあるでよ)](http://qiita.com/khirose/items/11dae9f4650767d20c4f)

を参考にshowSaveDialogを取り込みます。

# パッチ

ということで、パッチは

```javascript:patch
--- package.json.orig	Tue Jul 04 14:39:29 2017
+++ package.json	Wed Jul 12 18:19:16 2017
@@ -19,5 +19,8 @@
   "homepage": "https://github.com/anydown/mangadown#readme",
   "devDependencies": {
     "buble": "^0.15.2"
+  },
+  "dependencies": {
+    "data-uri-to-buffer": "0.0.4"
   }
 }
--- index.js.orig	Thu Jun 29 09:57:00 2017
+++ index.js	Wed Jul 12 18:27:05 2017
@@ -67,6 +67,19 @@
 var w = 420 + 20 * 2
 var h = (280 + 20) * 4 + 20
 
+const remote = require('electron').remote
+const os = remote.require('os')
+const fs = remote.require('fs')
+
+const path = require('path')
+const desktopDirName = 'Desktop'
+const homeDirPath = os.homedir()
+const desktopDirPath = path.join(homeDirPath, desktopDirName)
+
+const dataUriToBuffer = remote.require('data-uri-to-buffer')
+const dialog = remote.dialog
+
 new Vue({
   el: "#app",
   data: {
@@ -141,7 +154,26 @@
       destCtx.fillRect(0, 0, w, h)
       destCtx.drawImage(canvas, 0, 0);
       destCtx.drawImage(fabel, 0, 0);
-      window.open(eimage.toDataURL('image/png'));
+      //window.open(eimage.toDataURL('image/png'));
+      const canvasDataUrl = eimage.toDataURL('image/png')
+      const decoded = dataUriToBuffer(canvasDataUrl)
+      dialog.showSaveDialog(null, {
+          title: '画像の保存',
+          defaultPath: desktopDirPath,
+          filters: [
+              { name: 'PNG File', extensions: ['png']},
+              { name: 'All Files', extensions: ['*'] }
+          ]
+      }, (saveFiles) => {
+          fs.writeFile(saveFiles, decoded, (err) => {
+            if (err) {
+              window.alert('ファイルの保存に失敗しました')
+              console.log(err)
+            } else {
+              window.alert('ファイルを保存しました')
+            }
+          });
+      });
     },
     redraw: function () {
       var text = this.input
```

のようになりました。

パッチはGISTからもどうぞ。
https://gist.github.com/acknpop/bbc83020dedc90c28c5161836400c72d

このパッチを当てて、

```shell-session
> npm install data-uri-to-buffer
> npm run build
```

してから、electron-packagerでデスクトップ化できます。

> package.jsonのdependenciesを書き忘れてて、node_modules下がパッケージに組み込まれず、小一時間悩んでいたのはナイショです。

フォントと文字描画方法を変えてやれば、スコット・アダムスのディルバート風４コマメーカーも作れそうですね（やらないけど）。

以上。