LoginSignup
4

More than 1 year has passed since last update.

Web上でカメラ撮影してJavaScriptで処理したい

Last updated at Posted at 2019-03-23

最近、Webアプリでカメラで撮ったものをWebAPIに投げたい、というのを何度か書いており、ついでにここに書いておきます。

PC

Media Streams APIを使って画像に変換する、ということにしました。

お役立ちドキュメントは以下です。

雑に使うだけなら、enumerateDevicesは使わなくてもできますが、カメラを選ばせたいときは必要です。

また、上記のサンプルコードには書いてないですが、MediaStreamもリソースなのでちゃんと閉じる処理を書く必要があります。
具体的には、Mediastream#getTracksでMediaTrackを複数取得し、その後、MediaTrack#stopを呼ぶ感じです。

以下、Vueでそれっぽく実装したデモです。
ボタンを押したらCanvasに転写して画像データをURLに変換してImageタグを埋め込むだけです。

Demo: https://jsfiddle.net/4r8djy7c/

カメラが無いデバイスだと、mediaDevices.getUserMediaで失敗するので、catchでいい感じにやりましょう。

SmartPhone

なんでPCとSmartPhoneを分けているかというと、SmartPhoneではうまく動作しなかったからです。頑張って書いたのに!

同じコードで動かず悩みましたが、別のワークアラウンドを使う事にしました。
以下のように<input type="file">capture属性を付けるとカメラで撮影したものをファイルとして扱えるようになります。

一応、すぐに試せるのがあったほうが良いと思い、簡単ですが動くやつを書きました。モバイル用にQRも乗っけておきます

Demo: https://jsfiddle.net/fw4jyn95/1/

image.png
https://fiddle.jshell.net/fw4jyn95/1/show/

これはW3CのDevice and Sensors WGの成果物で、現状、SmartphoneのAndroidやiPhone等で動作します。ステータスは・・・どうなんだろう?

また、capture属性にはenvironment(リアカメラ)かuser(フロントカメラ)のいずれかを与えます。大半はenvironmentで問題ないですが、地鶏アプリならuserという感じです。
なお、PCで使ってたMediaStream APIでも同様にどちらのカメラを使うようにするか設定ができます。

このおかげで、導線はボタンを用意するだけで、UIもカメラの許可/拒否もデバイスに丸投げ出来ます。良いですね。

次に、<input type="file">の見た目が良くないのでボタンにしたい!となると思います。
そうなると、display: noneで隠して別のボタンからclickさせる等をするのですが、もしcreateElementを使う方法でやる場合は、以下の点も注意してください。

iOS-Safariで<input type="file">のChangeイベントを拾うときの注意
https://qiita.com/fukasawah/items/b9dc732d95d99551013d

蛇足ですが、PCとSmartphoneの判断をUserAgentで行う場合、wootheeが便利です。
https://github.com/woothee/woothee

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4