無料ウェブカメラフォトブース
ブラウザで直接Webカメラで写真を撮影します。フィルターとタイマーを適用して、写真をローカルに保存します。
仕組み
- カメラを許可: 「カメラを開始」をクリックして、ブラウザが要求したらアクセスを許可します。
- オプションを設定: シャッターを切る前に位置を整えたい場合は、フィルターを選択し、ミラーモードを有効にして、タイマーを設定します。
- キャプチャしてダウンロード: 「写真を撮る」をクリックします。撮影された写真はギャラリーに蓄積され、個別に、またはバッチでダウンロードできます。
よくある質問
写真はオンラインに送信されますか?
いいえ。すべての処理はMediaDevices APIを介してブラウザ内で行われます。画像がデバイスを離れることはありません。サーバーが動画ストリームを見たり保存したりすることはありません。
なぜカメラが起動しないのですか?
ブラウザの設定でカメラへのアクセスを許可していること、サイトがHTTPS経由で提供されていること(カメラアクセスに必要)、他のアプリケーションがすでに使用していないことを確認してください。
複数のWebカメラから選択できますか?
はい。複数のカメラが接続されている場合、「カメラ」セレクタにすべてが表示されます: 内蔵Webカメラ、外部USB Webカメラ、仮想カメラなど。
ブラウザのウェブカメラの実際の仕組み
ブラウザのカメラアクセスはW3CのMedia Capture and Streams仕様によって管理されている。エントリーポイントはnavigator.mediaDevices.getUserMedia():ページがストリームの種類を記述したconstraintsオブジェクトを渡して呼び出す関数だ。ブラウザが権限プロンプトを表示し、許可すると関数は1つ以上のビデオトラックを含むMediaStreamオブジェクトで解決する。ページはそのストリームを<video>要素にvideo.srcObject = streamでバインドし、ライブフィードが画面に表示される。ユーザーが「写真を撮る」をクリックした瞬間にHTML5の<canvas>にビデオを描画することでフレームをキャプチャする。キャンバスはcanvas.toBlob('image/jpeg')でエクスポートされ、ダウンロード可能なJPGになる。フレームはデバイスから出ることなく、パイプライン全体がブラウザのプロセス内で完結する。
PromiseベースのgetUserMediaがプレフィックスなしでChrome 53(2016年9月)とFirefox 36(2015年2月)に搭載された。Safariは遅れをとっており、ウェブページからのウェブカメラアクセスはiOS 11(2017年9月)までiOSに搭載されなかった。現代の安定したターゲットはiOS 14.5以降だ。2026年までにこのAPIは事実上ユニバーサルになり、caniuseではグローバルサポートが97%以上とされている。
HTTPSが必須の理由
getUserMediaは「セキュアコンテキスト」、HTTPS、デスクトップのlocalhost、またはFirefoxのfile://に制限されている。HTTPで配信されたページはカメラにまったくアクセスできず、呼び出しはNotAllowedErrorで拒否される。これはこの種のツールのセルフホスティング版で最もよく発生するデプロイ時のバグで、あらゆる現代ブラウザで一律に強制されている。モバイルはさらに厳しく、スマートフォンにはlocalhostの例外はないため、ローカル開発サーバーでカメラツールをテストするにはngrokのようなトンネリングツールかTLS付きのリバースプロキシが必要だ。
Constraints:適切なカメラを要求する方法
constraintsオブジェクトはAPIで最も複雑な部分だ。よく使う設定項目:
- width / height:数値または
min、ideal、max、exactを持つオブジェクトを受け付ける。idealが実際のデフォルトで、ブラウザは完全に一致しないカメラを拒否せずできる限り近い値にする。exactはハードウェアが対応できない場合に拒否する。 - facingMode:前面(自撮り)カメラには
'user'、背面カメラには'environment'を指定する。カメラが1つしかないノートパソコンではこのconstraintはサイレントに無視される。スマートフォンではデバイスを列挙せずに適切なレンズを選ぶ最も簡単な方法だ。 - frameRate:ほとんどのウェブカメラは30 fps上限で、一部の外付けUSBカメラは60 fpsに達する。
- deviceId:
navigator.mediaDevices.enumerateDevices()で列挙した後に特定のデバイスを選ぶために使う。重要な注意点:labelはそのセッションで少なくとも1回のカメラ権限が付与されるまで空文字列になる。そのため、権限付与前に実行される「カメラを選ぶ」ドロップダウンはラベルなしのIDを表示する。上のカメラドロップダウンは「カメラを起動」成功後にのみ入力することでこれを回避している。
カメラのランプが信頼の証
2008年以降のMacのウェブカメラでは、カメラの隣の緑色のLEDがセンサーと同じ電源ラインに配線されている。macOSとファームウェアはセンサーに電力が供給されている間は常にLEDが点灯するよう強制しており、Appleはカーネルレベルのマルウェアでさえカメラが録画中にLEDを消せないよう設計した。iOSはiOS 14(2020年9月リリース)以降、画面上部にオレンジのドットインジケーターを実装しており、アプリが抑制できないシステムプロセスによって描画される。Windowsのウェブカメラは最新デバイスのほとんどで同様のアプローチを採用しているが、強制力は一様でなく、2010年頃の一部のUSBウェブカメラにはソフトウェアで制御されるLEDがあった。Linuxはハードウェアによって異なる。
要点:LEDを信頼すること、ウェブサイトの言葉ではなく。このようなブラウザオンリーのツールはデバイスから何も出ないと誠実に約束できるし、カメラのランプはページが消灯していると言ったときに実際にカメラがオフになっているという独立した確認を提供する。ウェブカメラツールで最もよくあるバグは、閉じるときにstream.getTracks().forEach(t => t.stop())を呼び出し忘れることで、症状はユーザーが終了したと思った後もカメラのランプが点灯し続けることだ。このページの「カメラを停止」ボタンはそれを明示的に呼び出す。
ブラウザのウェブカメラツールを使う場面
- プロフィール画像の素早い撮影:Slack、Discord、GitHub、ソーシャルメディア用に、別のウェブカメラアプリをインストールせずに使える。
- パスポート・証明写真スタイルの撮影:オンラインフォーム(運転免許の更新、ビザ申請)用に自宅で撮影する。顔写真をサードパーティのサービスにアップロードすることに抵抗がある場合に、ブラウザベースのプライバシー保護は特に重要だ。
- ビデオ会議の事前確認:ZoomやTeamsの通話に参加する前に、照明、フレーミング、バーチャル背景の見え方を確認する。
- 学校・リモートワークの出席確認:先生や雇用者が存在確認のために素早い自撮り写真を求める場合に使う。
- アートとデザインの参照撮影:手のポーズ、3Dモデル用のオブジェクト写真、自画像スケッチなど。
- イベントでの簡易フォトブース:専用ページを表示したノートパソコンを設置し、ゲストがアプリをインストールせずに自撮りできるようにする。
- モックアップとプロトタイピング:「自撮り」ステップを含むフローを構築するデザイナーが素早くテストするページとして使う。
- 教育デモ:現代のウェブカメラAPIの仕組みを学生に見せる教師が使う。
macOSのPhoto BoothやWindowsのカメラアプリとの違いは、何もインストールされず何もアップロードされないことだ。ソフトウェアをインストールできない会社のロックされたパソコンや共有キオスクで特に役立つ。
フィルター:CSSのfilterプロパティで何ができるか
HTML5のキャンバスはctx.filterプロパティを通じてCSSフィルター構文を適用できる。上で利用可能なフィルターはCSSルールが適用できるのと同じプリミティブを使用する:grayscale(1)(完全な彩度除去、輝度射影に相当)、sepia(1)(古い写真を模倣したウォームブラウントーン)、invert(1)(色反転)、blur(5px)(ガウスぼかし)、brightness(1.4)(ピクセル輝度の乗算)、contrast(1.4)(中間グレーを基点としたピボット)。これらはChrome 53 / Firefox 35 / Safari 9.1以降すべてのブラウザでハードウェアアクセラレーションが効いている。
微妙だが重要な注意点:<video>要素に適用されたCSSフィルターはキャンバスには伝播しない。フィルターを保存するJPGに焼き付けるには、ctx.filterにdrawImageの前に同じフィルターを設定する必要がある。このページはそうしているため、画面上のプレビューと保存されたファイルはピクセル単位で一致する。
よくあるエラーとその意味
カメラの起動が失敗した場合、拒否は以下のいずれかの名前を持つDOMExceptionとして返される:
- NotAllowedError:(現在または以前のセッションで)権限を拒否したか、ページがHTTPSでない。アドレスバーのサイト権限メニューを確認し、カメラが「許可」または「確認する」に設定されていることを確かめること。
- NotFoundError:一致するデバイスが見つからない。背面カメラのないデスクトップで
facingMode: 'environment'にexactを指定して要求した場合によく発生する。 - NotReadableError:ハードウェアが別のアプリで使用中だ。Zoom、Teams、OBS、または別のブラウザタブがカメラを開いている。それらを閉じて再試行する。
- OverconstrainedError:constraintsを満たせなかった。
exactの要件を外すか、解像度を緩和すること。 - TypeError:constraintsオブジェクトが空だ。呼び出しはaudioまたはvideoの少なくとも一方を要求する必要がある。
よくある質問
画像が上下逆さまや横向きになるのはなぜか?
一部のAndroidカメラはEXIFメタデータに誤った回転情報を記録する。ブラウザは通常、ビデオフレームがキャンバスに届く前に自動的に回転を適用するが、古いSamsung Internetバージョンや一部の埋め込みWebViewはこの手順をスキップする。キャプチャが横向きになる場合は、撮影前にデバイスを90°回転させるか、撮影後に「画像を回転」ツールを使うこと。
ドロップダウンに名前ではなく「カメラ 1、カメラ 2」と表示されるのはなぜか?
ブラウザにまだカメラ権限が付与されていないためだ。enumerateDevices()は現在のセッションでユーザーが少なくとも1回カメラアクセスを承認した後でのみラベル(例:「FaceTime HD Camera」)を返す。それまでは不透明なIDのみが返される。「カメラを起動」を1回クリックしてアクセスを許可すると、ドロップダウンが適切な名前で更新される。
ページを閉じた後もカメラのランプは点灯したままになるか?
いいえ。「カメラを停止」ボタンはストリームのすべてのトラックを明示的に停止し、モダンブラウザはタブが非表示になったりページがアンロードされたときもトラックを停止する。タブを閉じた後もカメラのLEDが点灯したままになる場合、それはフラグを立てる価値のあるバグで、多くはページがクリーンアップ関数を呼び出さなかったことを意味する。このツールでは「カメラを停止」をクリックするか、タブを閉じると直ちにハードウェアが解放される。
静止画だけでなく動画も録画できるか?
このツールはできない。静止画のキャプチャのみだ。動画の録画にはMediaRecorder APIが必要で、ブラウザによってWebM、MP4、MKVのファイルが生成される。録画にはそれ自体のプライバシー上の意味合いもあり(識別可能な映像をより大量に保存することになる)、独自の専用ツールで扱う価値がある別のユースケースだ。
何かサーバーに送信されるか?
いいえ。ビデオストリームはOSからブラウザに直接配信される。キャンバスのキャプチャとJPGエクスポートはJavaScriptを使ってローカルで行われる。ギャラリーはブラウザメモリ上に存在し、デバイスに直接ダウンロードされる。カメラ、顔、写真に関する情報はページから出ない。