点描.click

社長:なんか面白い事したいですね。

開発:昔からの夢だった、世界で一つだけのホワイトボードを作ってみたいと思います。

社長:誰でも書き込めるOneNote みたいなやつですかね。

基盤:JavaScriptでAjaxとかいうやつかな。

開発:いえ、とりあえずクリッカブルマップでPNGかなと。

社長:Google Mapsに書き込むようなやつですかね。

基盤:Google Earthみたいなやつかな?

開発:いえ、とりあえずいわゆる点描です。

社長:詳しく。

開発:いえ、今の所それ以上のものではありません。まあキャンバスはフラクタルになってて無限にズームイン・アウトができたり、時間を自由に前後できると良いなとは思いますが。

基盤:NASA でしたっけ、3Dで宇宙のいろんな視点で遠ざかったり近づいた入りして見れるアプリ出してましたね。

開発:いえ、とりあえず2Dのみです。ただし、点には自由に属性を付けられる。点は要するに座標情報です。その座標に属性を付ける。一番シンプルなのが、その点を表示する色です。それだけであれば、まさに点描画ということになります。まあ、トランスペアレントにすれば、何にでも重ねて点を打つことはできるはずです。

社長:ふーむ。思い切りスモールスタートというか、マイクロスタートですね。わかりました、ドメイン名を取て気分を盛り上げましょう。点描… pointillism、ポインティリズムっていうんですか。では、安いところで pointillism.click と 点描.jp をポチッと。

開発:べたですね。

基盤:取った名前をXSOのサイトに流用されないように、取得後速攻でNSを当社ネームサーバに向けないと… はい、大丈夫のようです。開通即自社サイト向きになりました。

基盤:まあ100歩譲って名前のアドレスを登録するまで使ってくれてもいいけいど、使用料を払うべき。そして、アドレスが登録されたら速攻で、新しいアドレスのほうへの転送に切り替えるべき。そう思いますね。

社長:いわゆるクリッカブルマップで90年代の技術だと思いますが、現状では何がそれに相当するんですかね?

開発:まずそこから調べようかと。それはそうと、朝目が覚めた時にスマホの小さい文字が読めないのが辛いですね。特に最近ルテインを飲み忘れてるせいなのか…

* * *

社長:とりあえずお腹が空いたので飯に行きますか。

基盤:昨夜から外が荒れ模様でイマイチ出たくないですね。昨日買った辛ラーメンで済ますとか。

経理:先程のドメイン代金の出費もありますし。

社長:そうですか。… これって以前一度食べたことがあるのですが、少し辛さがマイルドになったような。ズズっ。

基盤:袋麺をカップにつめたらこうなりましたみたいな感じですね。麺に工夫が無いのがある意味斬新です。ズズッ。

開発:しいたけの切れ端なんて載ってましたっけね。おかげでか少し旨味が感じられるようにも思います。ズズ。

社長:あとこのカップ、以前はもっと薄っぺらくて、とても手で持てなかったような気がするのですが。今日は持てますね。お湯の温度が低めだったからですかね。ズズっ。

経理:ズズ。ゲホゲホ。ケホッ。完食いたしました。これ、100円はまあ、妥当な価格かなとも思います。

* * *

基盤:この麦茶のほうが高かったりして。

経理:コンビニとか自販機で買ったら高いですね。

社長:当社認定の麦茶はサントリーのやさしい麦茶と決まっております。以前はつるべの麦茶で、デビュー当時は香りも味もキリッとしていてとても良いと思っていたのですが、ちょっときついとも感じてました。でこのやさしい麦茶というのが出て飲んでみたら、とてもやさしくて気に入ったのです。

経理:現在ゥエルシァの棚ではつるべが4列、やさしい麦茶が3列ですね。

社長:いずれ逆転すると思いますよ。

基盤:これの良い点は、ラベルが剥がしやすい点ですね。ゴミ捨てにもやさしい。

開発:てか私は、ラベルを剥がして捨てるっていう作業自体の意味がわからないんですけどね。それよって最終的にどういう総合的なコストになっているのか。ラベルを剥がす作業自体だって、人件費として累積計算すれば馬鹿にならない。アマチュアがやるよりプロとか機械でやるほうが効率が良いと思うんですが。あるいは、いっそラベルは紙にするとか。

基盤:何にしても、剥がすのに苦労するようなボトルを作ってる会社はその時点でアウトですね。

社長:レジ袋も昔みたいに紙袋になったら面白いですね。めぞん一刻で響子さんが買い物帰りに抱えてた紙袋が、途中からぶら下げ型のレジ袋に変わったのを記憶していますが、あれはその当時から見た目に趣きがないなと思ったものです。

開発:レジ袋は自宅での小分けのゴミ袋としても便利だったんですけどね。レジ袋が少なくなったら、結局、別途ビニールの小分けゴミ袋を買って使っているという無駄。

経理:今的なら、お買い物はマイバッグってことになるんでしょうけど。

基盤:そしてやがて宅配になって人がレジに並ぶこともなくなるのです。

* * *

開発:さてそれでクリッカブルマップですが、その後は JavaScript でマウスのアクションを拾って、必要な時に座標をサーバに投げるという事になっているんだと思います。というか、普通はクライアントの中でクリックした区画によってアクションを規定する。クライアントの中で閉じた動作かも知れません。

開発:一方いまやりたいことは、その点が何を意味しているかはサーバが解釈する。クリックごとにサーバに座標を投げる、というものです。で、その結果何らかのアクションをしてオリジナルのマップなり解釈なりを変える。それを全クライアントに周知する。周知するのはとりあえず簡単とは思えないので、これはクライアントによるリロードを待つことにします。

開発:クライアント側のアクションでサーバに対するリクエストを発生させると言えば、古典的なHTTPの手法では A か FORM かと思います。でこの場合はもちろんFORMですが、HTMLの仕様を見ると、どうも input の要素として image Button という属性があるらしい。

開発:というところで引っかかってしまったのですが、何のことはない、type=subumit とか type=button と同じように、type=image と書けば良いのだということがわかりました。なので、点描.click の最初の一歩はこれです。単なるクリッカブルマップですが(笑)

基盤:form の action とかオプションだとは知りませんでした(^-^;)

開発:それで、早速クリックされた部分のピクセルを変えるとかしたいところですが、PNGの生成とか面倒なんで後の楽しみにします。

開発:そもそも思うに、バイナリじゃない画像表現が無いものかと思うんです。PNG互換で良いとしたら、それを単にシンボリックにテキストで表現するニモニック的なものでも良いです。Portable Textual Graphics とか。まあそれと、PNGを相互変換するツールを作れば良いと思いますが。PostScriptというのはそういうものだったかも知れないですけど。

開発:それで次にやりたいのは、複数のクライアントからパラパラとやってくるクリック情報を集積して全員に見えるようにすること、あと単に座標だけでなく何かの属性情報も受け取って集積したい。どこに集積するかと言うと、これはmethodがGETであれば、単にHTTPのアクセスログでも良いです。ただ、このページだけのログが、永続的なものとして欲しい。

社長:例えば 1024 x 1024 の画像を1点ずつ全部埋めたら、上書き無しとしても 100万件のアクセスログになるわけですね。

開発:今の計算機のリソースから考えればたいしたことでは無いですね。

基盤:ただ、ログからの合成を考えると、座標ごとのログに分かれていたほうが良いようにも思います。

開発:プロトタイプというかモックアップの段階では性能のことは考えません。一桁二桁遅かったり大きくても無問題です。標準形式とかも考慮しません。

開発:HTTPのログの情報の中で使用するものとしては、日付、アクセス元、URL の query 部分つまり座標と属性が必須です。他の部分も役に立つとは思います。

開発:べたにファイルに追加していくとして、時刻で2分サーチはしたいとかありますから、固定長が望ましい。テキストとして見たいので、Base16でやるとすると、32ビットが8バイト。これを4つ使うとして32バイトということになります。まあ区切りの空白も入れたり当面の拡張性も考えたりで、1レコード64バイトかなと。これだとテキストとして端末で見る時に見やすい。1メガピクセルの画像が64MBという計算です。

社長:というかそのログ自体が、画像表現形式でもあるわけですね。

* * *

開発:というわけで、とりあえず第一モックアップを作って、クラウド上のサーバにアップロードしました。

基盤:記述言語は?

開発:それは極秘です(笑)。表示している画像のサイズは、幅が400ピクセル。真っ黒画面で、pngにして16KBしかありません。この上でチクチククリックするたびにサーバとやり取りするわけですが、0.1秒以下で転送終了するので、ローカルホスト上のサーバで実験した場合と感覚的にはほとんど変わらない応答性です。

社長:ノートが付けられるから、この部分で昔あった駅の掲示板程度には使えそうですね。

基盤:やはりundoはしたいですね。

開発:おっと、MacMini が勝手にリブートしました。ちょっといじめ過ぎですかね…

開発:自分の打った点を取り消したりしたいですしね。キャンバスのリセットの権限というのもあるから、やはり何らかの認証は必要かなと思います。

社長:権限やIDごとに表示、非表示とか、重ねる層とかもできると良いですね。

開発:とりあえず点描でやってますが、最終的には四角とか円とかテキストとか、そういうオブジェクトを置くことになるんでしょうね。HTMLのcanvasを共有できるみたいにするのが理想形なのかなとは思います。

基盤:しかしそういう事を始めると、それこそ昔からありがちなツールになりそうですが。

開発:まあ我々の空白の間の歴史を追体験をするわけですね。自分で体験的に作っていくうちに何か面白い発見ができたら、儲けものという。アプリの機能というよりは、現在のコンピュータのリソースとネットワーク環境で性能的に何ができるのかなとか。

基盤:そういえば昨日計測したところでは、Amazon Lightsail はダウンロードが 15MB/s くらい出ますね。Azureでは5MB/s、XSOのレンタルサーバが10MB/sくらいでしたから、意外でした。ますます、ライトセール一択です。

社長:とりあえずこの掲示板的モックにロボットさんがやってくるかが見ものですね。ぜひ、ロボットがクリックしたくなるような何かを仕掛けたいものです。

開発:クライアント側で区画を決めるクリッカブルと違って、古典テクなマップはサーバ側でしかその区画的構造の意味を知らないですから、いかなロボットと言えども狙い撃ちは難しいんじゃないかと思うのですが。

基盤:そう言えば最近、XSOの管理者コンソールが、私はロボットではありません版 Google reCAPTCHAをやめてしまって、例の信号機だのトラクターだの選べというやつになってウザくなりました。

社長:なぜデジタル証明書でクライアント認証しないんでしょうね?sshでログインスルときには顔パス的にしてるのに。管理用のHTTPをSSHの口から入らせても良いと思うし。

基盤:端末からssh した時に私はロボットではありませんてのがCLI的に出てきたら面白いですね。

開発:そういえば最近、MSだかアマゾンだかで、昔流の文字認識をさせるやつにも出会って超不愉快でした。reCAPTCHAで何か不具合があったんですかねえ?

* * *

基盤:点描.click を見てて気づいたのですが、各ページごとにアクセスログが簡単に見えるってとても便利ですね。

開発:アクセス者のプライバシー保護という観点では、通常のアクセスログと同じレベルで管理する必要はあると思いますが、コンテンツ情報とそれに付随する情報が同じ塊として切り分けられていて管理できるのは良いと思います。特にこの場合、アクセスのログからコンテツが生成されるので、ログ≒コンテンツのようなものです。

社長:サーバ単位のアクセスログだと膨大になってしまい、長期の保存とか統計分析が難しくなりますが、注目したいリソース、特にHTMLのページやダウンロード用ファイルのログは全体のごく一部ということがほとんどですから、それだけを特出しでログの形にしておけるのは良いですね。実際、サーバがログを作成する際に、全体のログに書くのと同時に、個別リソース毎のログに書くようにするというのは、技術的には簡単な事です。

基盤:たとえば10年間で10万回のアクセスのあるページにしても、各アクセスログを 0.25KB程度とすれば、100,000*0.25KB、25,000KB、わずか25MBということになりますね。とても扱いやすいサイズで、そこから統計を作るのも簡単。しかもそんな人気ページは滅多にないと思います。通常は、他のログと一緒くたにアーカイブされてしまったりして、後から参照するのが簡単ではなくなるのが嫌。

* * *

開発:それで、点情報の列を画像にする方法ですが、ぱっと考えられる方法は2つ。1つはGoに食わせてPNGにする。もうひとつはJavaScriptに食わせてCanvasに書かせる。前者は以前プログラム例を見ているので、簡単なことがわかっています。後者はもっと初歩的な話です。こちらはインタラクティブな更新が可能ですが、描画点数が多数になると厳しい。なので、PNGでまずロードして、差分をJavaScriptで加えたり削ったりしていくというのが実際的かなと思います。JavaScriptでは、点ではなくて部品単位の図を扱うのに良いのかなと思います。PNGを背景にしてJavaScriptで描くというのが自然かなとは思います。

開発:ということで、まずはGoで描くことにします。このマシンでこのサイズのPNGを生成するGoの実行は、go run だと 250ms以上かかってしまうので、ヒトが意識する応答性に支障をきたしますが、ネイティブコード版であれば10msです。通信が100msかかると見込まれますし、いずれにしてもヒトが感じ取れる遅延要因にはならないと思われます。

開発:さてそれで最大の難所はGoでsscanf相当をどうやってやるかなのですが、package bufio で無駄な回り道をした後、fmt.Sscanfというのがあることがわかりました(笑)。

開発:で、さっそくポチポチと点描をしてみたのですが、200点くらいで疲れました。こんな感じ。

社長:よくわからないですが、宇宙の大規模構造のようにも見えますね(笑)

開発:それでつくづくおもったのですが、これ式でやるとすると、HTTPサーバは専用に分けないと、アクセスログがとんでもないことになってしまうということです。

基盤:そうですね。ではライトセールで点描専用のサーバを作ります。

開発:あと、PNGは赤い点ばかりなので圧縮が効くのでしょう、200点でも1KB程度です。ですがいずれ、区画ごとにPNGを分けた版を作るとか、分けて生成して結合することも必要と思います。

社長:分割して作るなら、座標的にはもう無限大でいけますね。

開発:あとこれは、単に X, Y, R, G, B, A の値の羅列なので、これもまた一種の画像フォーマットかなと思います。きっと、PNG のそのほかのチャンクと合わせて、PNGのテキスト表現フォーマットとかあるのでは無いかと思います。Z軸も入れて3次元にということも考えられます。ですが、Z軸は別のレイヤのPNGにというのが自然かなとは思います。

基盤:時間軸と合わせて4Dから2Dのアニメーションを切り出すのは面白そうです。

社長:で、それに対してクリア署名かQR署名をすると、我々の野望は達成ですね(^-^)

-- 2020-0701 SatoxITS