PaPoo
cover
technews
Author
technews
世界の技術ニュースをリアルタイムでキャッチし、日本語でわかりやすく発信。AI・半導体・スタートアップから規制動向まで、グローバルテックシーンの「今」をお届けします。

古いUSBスキャナーをブラウザでよみがえらせる「Yes We Scan」の仕組みと発想

要点

古いスキャナーを、もう一度使いたい

この記事の主役は、​​「古いUSBスキャナーを、今のPCから使えない問題」​をどうにかしようというWeb appです。

最近のパソコンは、昔の周辺機器に冷たいです。とくにスキャナーは、メーカーのドライバが古かったり、そもそもOSが変わってもう動かなかったりして、押し入れに眠りがち。
この記事の作者も、まさにそんな状況に遭遇していたようです。

きっかけは、もともと両親や義理の両親のために古いCanon製プリンターを使えるようにした printervention.app。その開発中に、「そういえば、棚に古いCanonのUSBスキャナーもあるじゃん」と思い出した、と。
この流れ、すごくわかります。ひとつ困りごとを解決すると、​**“あ、これもいけるのでは?”** と芋づる式に発想が広がるんですよね。技術好きあるあるです。

何をしているのかを一言でいうと

ブラウザの中に仮想マシンを作り、その中でLinuxとスキャナー用ソフトを動かしている、というのが大枠です。

かなり荒っぽく見えますが、これがこのアプリの面白いところ。
普通は「ブラウザでスキャンしたい」となると、Web APIで直接スキャナーにアクセスする方法を考えそうです。ですがこの作者は、もっと大胆に “スキャナーを動かすための環境ごとブラウザに持ち込む” 方向を選んでいます。

これは発想としてかなり好きです。
「ブラウザに不足しているなら、ブラウザの中に必要なものを全部入れてしまえ」という、ある種の力業ですが、ちゃんと成立しているのがすごい。

中心にあるのは v86

この仕組みの核は v86 です。
v86は、​x86 CPUだけでなく、その周辺を含めた“パソコン一式”をブラウザ内でエミュレートする技術です。

エミュレートとは、ざっくり言えば別の機械をソフトウェアでまねすること
つまり、古いPCをブラウザの中で再現してしまうようなものです。

しかも v86 は、機械語を WebAssembly に実行時変換するので、ただの「遅い仮想PC」ではありません。
ここは地味に重要で、ブラウザ内でそれなりの速度を出せる理由になっています。もちろん本物のネイティブ実行には及ばないでしょうが、動かすこと自体が大変な領域なので、これはかなり立派です。

LinuxとSANEをブラウザで動かす

作者は、v86 の仮想マシンの中で Alpine Linux を動かし、その上で SANE (Scanner Access Now Easy) を実行しています。

SANEは、Linux系でよく使われるスキャナー用のソフトウェア基盤です。
名前はちょっとふざけている感じですが、役割は真面目。スキャナーを扱うための共通インターフェースのようなものだと思えばよいです。

つまり、流れとしてはこんな感じです。

  1. ブラウザ内で仮想マシンを起動する
  2. その中で Alpine Linux を動かす
  3. Linux上で SANE を動かす
  4. SANE からスキャナーを操作する

この構成は、素朴に言えばかなり重そうです。
でも、「古い機器を今のブラウザで使いたい」という目的に対しては、かなり筋が通っています。古い周辺機器問題の本質って、実はハードよりソフトウェア互換性の断絶にあるので、こういう“環境ごと持ち込む”アプローチは合理的だと思います。

ブラウザとSANEの橋渡しは、小さなCプログラム

では、ブラウザの世界と、仮想マシン内のSANEはどうやって会話しているのでしょうか。

ここで登場するのが、作者いわく Claudeの助けを借りて書いた小さなCプログラムです。
このプログラムが、

という役割を担っています。

JSONは、データを扱いやすい形で表すテキスト形式です。
つまり、スキャナーの設定を「ブラウザ側でUIを作るために読みやすい形」にして渡しているわけです。

ここも面白いポイントです。
単にスキャンできればいいのではなく、​設定UIまで自動で組み立てられるようにしているのが、かなりちゃんとした作りです。古い機器をただ「動く」だけで終わらせず、​使いやすさまで考えているのが好印象でした。

スキャン結果はどう表示・保存するのか

ブラウザ側では、受け取ったスキャンデータを次のように扱っています。

この構成もなかなかスマートです。
プレビューでは軽く描画し、保存時にはちゃんと圧縮する。処理を役割分担しているわけです。
個人的には、こういう**“見せる処理”と“保存する処理”を分ける設計**はかなり好きです。雑に全部メインスレッドでやると、ブラウザはすぐもっさりしますからね。

いちばん驚くのは USB/IP と WebUSB の橋渡し

このアプリの真骨頂は、やはり USB側の接続です。

作者はすでに printervention.app で USB 周りを動かしていたそうで、そこからの応用になっています。
流れはこうです。

1. Linux側で USB/IP を使う

USB/IP は、USB通信をネットワーク越しにやり取りする仕組みです。
ざっくり言うと、​USBデータをTCPパケットに包んで送る技術。

SANEから見ると、まるで普通のUSBスキャナーにつながっているように見えます。
でも実際には、USB通信がネットワークっぽく運ばれている。ここがトリックです。

2. ブラウザ側で tcpip.js が動く

次に、JavaScript側では tcpip.js が動きます。
これは lwIP をWebAssemblyにコンパイルして使っているそうです。

lwIPは軽量なTCP/IPスタック、つまりネットワーク通信を扱うための基本ソフトです。
v86の仮想マシンには仮想ネットワークカードがありますが、ブラウザに届くのは生のEthernet frameです。
ところがブラウザには本物のネットワークスタックがないので、EthernetレベルのデータをTCP/IPに戻す役が必要になります。そこで tcpip.js が働く、というわけです。

この部分はかなり玄人向けですが、要するに
​「ブラウザはネットワークっぽい生データを受け取るだけなので、足りないTCP/IPの部分を自前で補っている」​
と考えるとわかりやすいです。

3. 最後に WebUSB で実機USBへ接続

再構成された USB/IP パケットは、最終的に WebUSB API を使って、あなたのパソコンのUSBポートへ流されます。

WebUSBは、ブラウザからUSBデバイスにアクセスするためのAPIです。
つまり、ここでようやくブラウザが、現実世界のUSBスキャナーとつながるわけです。

ここまで来ると、かなり壮観です。
ブラウザ → 仮想マシン → Linux → SANE → USB/IP → WebUSB → 実機スキャナー
という長い道のりを通って、ようやく1枚のスキャン画像が出てくる。
普通なら「もっと素直な方法はないの?」と思うかもしれませんが、古い機器を相手にすると、素直な方法が存在しないことも多いです。だからこそ、この迂回路は妙に説得力があります。

どのスキャナーで動くのか

記事では、​作者の CanoScan LiDE 100 でテストしたと書かれています。
ただし、それだけでなく、​数百種類のモデルで動く可能性があるとも述べています。対象メーカーには、

などが挙げられています。

ただし、これは実際に全部で動作確認したという意味ではありません。
あくまでSANEとUSB周りの互換性から見て、対応範囲が広そうだという話です。ここは期待しすぎず、でも夢はある、という距離感がちょうどいいと思います。

オープンソースではない点は少し残念

作者は、​まだコードの大部分をオープンソース化していないと、わざわざ謝っています。

これは少し残念ですが、実際にはこういう高度な個人開発では珍しくもないです。
全部公開するには整備が大変ですし、そもそも試行錯誤の途中で作られた部分も多いはず。
とはいえ、こういう面白い仕組みこそ公開されると他の人が応用できるので、将来的に何かしらの形で広がるといいな、とは思います。

率直な感想: 発想が「OSごと持ってくる」で気持ちいい

個人的にこの記事でいちばん面白かったのは、​ブラウザに機能を足すのではなく、必要な環境ごと持ってくるという割り切りです。

普通は「Webアプリでスキャナー制御したい」となると、ブラウザAPIの制約とにらめっこしながら小さく戦います。
でもこの作者は、v86、Linux、SANE、USB/IP、WebUSBを組み合わせて、かなり大きな解を作っています。

もちろん、これは万人向けの設計ではありません。
でも、​**“動くこと”を最優先にして、既存資産を救う**という意味では、とても強いアプローチです。
古い機器って、捨てるのは簡単だけど、使えたら十分価値があることも多いですからね。そういう意味で、このアプリはかなりロマンがあります。

まとめ

Yes We Scan は、古いUSBスキャナーをブラウザから使えるようにするための、かなり野心的なWeb appです。
v86で仮想マシンを動かし、その中でLinuxとSANEを使い、USB/IPやWebUSBまでつないでしまう。やっていることは相当複雑ですが、目的はとてもシンプルです。

​「もう使えないと思っていたスキャナーを、また使えるようにする」​
たったそれだけのために、ここまでやる。
その執念がまず面白いし、技術の力で“古いものにもう一度命を吹き込む”感じも気持ちいい。そんな記事でした。


参考: Yes We Scan: backstory and how it works

同じ著者の記事