diagrams.net を使って Qiita / Discord / 他に再編集可能な図を貼り付ける

Qiita や Discord で科学/技術/工学の話題では図式を貼り付けて説明していますが、その図式を後々再利用したいですね。

例えばこの図はビットマップ画像を Qiita に貼り付けています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8504bb82-f835-55e2-190d-f022c1a14c08.png)

これは png ファイルになってますが、元々はベクターグラフィックです。この図を含めて今までベクターグラフィックを LibreOffice Draw で描き、ファイルを経由せずに LibreOffice Draw 上のオブジェクトをコピペで Qiita に貼り付けていました。その場合、Qiita 側で勝手に png 形式に変換してくれています。

しかしながら png ファイルになってしまうとベクターグラフィックの再編集作業ができないですね。
例えば上記のオペアンプの図式に手を加えて非反転増幅回路や、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a5136ef8-7645-4316-b5af-dcebbee83326.png)

作動回路
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/74135e0c-0e4f-34c0-1020-d4511f660ad4.png)

にしていきたいのですが、
(cf.,https://qiita.com/nanbuwks/items/8a36a268a6f1e2d802e4)

それをするには Qiita の記事とは別に LibreOffice Draw の元図版ファイルを保持していて、それを元に書き足すことになります。

そうではなくて、Qiitaなどに図式を貼り付けた後、貼り付けた記事からグラフィックを回収してベクター編集を再びしたいですね。


VSCode や GitHub などでは SVG を Markdown に入れられるらしく、それができれば 編集ツールとして Inkscape などを使い、目的を達することができます。しかしながらそういうことはいつでもどこでもできるわけではありません。まず、Qiita は Markdown に一部のHTMLを含めることができますが、SVG は埋め込みはできません。
また、僕が手がける技術コミュニティ で利用する SNS として去年は Slack を主に使ってましたが最近は Discord に乗り換えています。Slack にしても、Discord も SVG 埋め込みはできないようです。

# diagrams.net を使う

この問題を解決するのに、 diagrams.net で作成した png ファイルを使うのが良さそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/06faba90-fd40-f69a-9ec4-3b6bd0c15cf5.png)

diagrams.net は無料のWebアプリで、上記のような図が作成できます。

## png ファイルを作成する

上述の画面から png ファイルにエクスポートできるのですが、その png ファイルには diagrams.net のネイティブデータを埋め込むことでき、png からベクター描画データが復元ができます。

出力したい範囲を選択して、「ファイル」-「形式を指定してエクスポート」を選びます。
以下のようにして png ファイルを出力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ea1b1034-f4c3-2336-7411-c8210175721a.png)

## Qiita へ貼り付け

出力した png ファイルを Qiita に貼り付けると以下のようになります。

![Page68-問題1.25クイズ.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c7a1000b-8ac0-9bf4-5a59-b2998a3e9d31.png)

## Qiita に貼り付けた図を再編集

この貼り付けた png ファイルを更にダウンロードして、diagrams.net にインポートすると以下のように復元しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/71ebdee1-5142-1fc2-2c1c-9488b31abeb9.png)

# Discord での再編集実験

以下のように、同様にファイル経由で貼り付け、再編集ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/26c3abda-ad4c-beda-fbb2-bd9f950940e6.png)


# Qiita / Discord とのやりとりのコツ

ファイルとして一旦保存、そこからQiita / Discord に貼り付けをしないと埋め込みデータは失われてしまうようです。
また、diagrams.net へインポートするときも一旦ファイルとしてダウンロードしないといけませんでした。

また、大きな画像ファイルを描いて一部分の図だけを Qiita などに貼り付けする場合は、「選択範囲のみ」を選択してエクスポートする必要があります。

以下は指定せずに4ページ目だけエクスポートした場合の png ファイルです。一見上に掲載したものと変わらないように見えますが・・・

![Page68-問題1.25クイズ.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0bdf1ceb-0aa9-1a3b-964d-c88f79514895.png)

これをインポートすると以下のように全ページが復元されてしまいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c33d01ca-68c9-cf3f-fbbe-6fb3f275ee5b.png)

# 仕組み

kaakaaさんの記事「*.drawio.png と *.drawio.svg とはなんなのか」
https://zenn.dev/kaakaa/articles/qiita-20200728-ff9ab5933cc0fb6fd8d8
では、

> PNG ファイルのzTXtチャンク、もしくはtEXtチャンクからグラフモデルを読み出しているようです。
tEXtチャンクの中身は、XML 要素ではないmxfileというワードで始まっていることと、パーセントエンコードされていること以外は、Draw.io のデータ保存形式と同じように見えます。実際、先頭のmxfileを外した XML をファイルに保存し、Draw.io Integration で開いてみたところ問題なく開けました。

とあります。

「PNG仕様書」で検索
https://www.google.com/search?q=PNG%E4%BB%95%E6%A7%98%E6%9B%B8
や
「PNG仕様書+チャンク」で検索
https://www.google.com/search?q=png%E4%BB%95%E6%A7%98%E6%9B%B8+%E3%83%81%E3%83%A3%E3%83%B3%E3%82%AF

こんなところから読み取れる情報だと、 tEXt または zTXt に任意長のテキスト情報を格納できるみたいですね。

なお、先に例を出したこのpng画像ですが、

![Page68-問題1.25クイズ.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c7a1000b-8ac0-9bf4-5a59-b2998a3e9d31.png)

エクスポート方法によってファイルサイズが以下のようになりました。

| サイズ(Bytes) |「ダイアグラムのコピーを含める」| 「選択範囲のみ」 |メモ|
|:---:|:---:|:---:|:---:|
| 24100 |□|☑|png画像イメージデータのみ|
| 29704 |☑|☑|png画像範囲分の元データーを含む|
| 40956 |☑|□|png画像範囲外を含む全元データを含む|

また diagrams.net のオリジナルのフォーマットは xml だそうですが、png 画像のもとになったデータを保存したファイルサイズが以下のようになりました。

| サイズ(Bytes) |「ダイアグラムのコピーを含める」|
|:---:|:---|
|5221|1ページ分(PNG画像該当箇所のみ)データ|
|15561|4ページ全部|

各 png 画像のサイズの関係が、最初の png 画像のサイズにオリジナルのデータサイズを足したのとほぼ同じサイズとなっているのが興味深いです。

# diagrams.net で感激!

再編集可能という以外にも、 diagrams.net は以下の点が素晴らしい!

- 無料。一般公開するデータを作るのに適している。
- サービスが提供の実績が長い。突如無償サービスする規約が変わる心配はあまり無さそうです。
- データの後方互換性が高い。
- デスクトップアプリがあり、マルチプラットフォーム対応。
- VSCode との連携が既に可能となっていて、エディタブル図式入のMarkdownが便利に作成できる。
- TeX 形式で数式が扱える。


# 残念なこと

diagrams.net はとても有用な描画ソフトですが、図式に特化しています。なのでお絵描きとしては弱いところがあります。例をざっと挙げると

- オブジェクトグループをまとめて拡大縮小するときに、線太と文字サイズが付いてこない
- 吹き出しシェイプの口の制御が(ほぼ)できない
- 塗りつぶしのグラデーションが弱い 
- オブジェクトの重ね合わせでの色演算ができない
- オブジェクトのブール演算ができない
- 閉曲線が作れない?
- 文字装飾が弱い
- 寸法線が無い
- ヘルプ検索が英語でないと動作しない
- ...

本質的に向いていないところもあるので仕方がないところがありますが、「あとちょっとできればいいのに」というところで悔しいのも事実。

svg データをチャンクで埋め込んだ png を作るツールを作ればいいのですけどね。

また、いちいちファイル経由しないといけないのも手間がかかりますね。VSCode を UI に使うとか、PNGファイルを出力する WebAPIを作るとかするのが解決策?