web-dev-qa-db-ja.com

カメラAndroid例

次のようなアクティビティを記述したいと思います。

  1. カメラのプレビュー(ビューファインダー)を表示し、「キャプチャ」ボタンがあります。
  2. 「キャプチャ」ボタンが押されると、写真を撮り、それを呼び出しアクティビティ(setResult()&finish())に返します。

すべてのデバイスで機能するcompleteの例はありますか?写真を撮るシンプルなオープンソースアプリケーションへのリンクが理想的な答えです。


これまでの私の研究:

これは一般的なシナリオであり、これには多くの質問とチュートリアルがあります。

主なアプローチは2つあります。

  1. Android.provider.MediaStore.ACTION_IMAGE_CAPTUREイベントを使用します。参照 この質問
  2. Camera APIを直接使用します。 この例 または この質問(参照が多い) を参照してください。

アプローチ1は完璧でしたが、問題は、意図がデバイスごとに異なる方法で実装されていることです。 一部のデバイスではうまく動作します。ただし、一部のデバイスでは写真を撮ることができますが、アプリに戻ることはありません。一部のデバイスでは、インテントを起動しても何も起こりません。 通常、画像をSDカードに保存し、SDカードが存在する必要があります。ユーザーの操作もすべてのデバイスで異なります。

アプローチ2では、問題は安定性です。いくつかの例を試しましたが、一部のデバイスでカメラが機能しないように(再起動するまで)停止し、別のデバイスを完全にフリーズしました。別のデバイスではキャプチャは機能しましたが、プレビューは黒のままでした。

私はサンプルアプリケーションとしてZXingを使用していましたが(私はそれを頻繁に使用しています)、プレビュー(ビューファインダー)のみを使用しており、写真を撮りません。また、一部のデバイスでは、照明条件が変更されたときにZXingがホワイトバランスを自動的に調整しませんでしたが、ネイティブカメラアプリは適切に調整しました(これが修正できるかどうかは不明です)。


更新:

しばらくの間、カメラAPIを直接使用しました。これにより、より多くのコントロール(カスタムUIなど)が提供されますが、誰にもお勧めしません。私はデバイスの90%で作業しましたが、時々、新しいデバイスがリリースされ、別の問題が発生しました。

私が遭遇した問題のいくつか:

  • オートフォーカスの処理
  • フラッシュの取り扱い
  • 前面カメラ、背面カメラ、またはその両方を備えたサポートデバイス
  • 各デバイスには、画面解像度、プレビュー解像度(常に画面解像度と一致するとは限りません)、および画像解像度の異なる組み合わせがあります。

したがって、他に方法がない場合を除いて、一般的に、このルートを使用することはお勧めしません。 2年後、私はカスタムコードでダンプし、インテントベースのアプローチに切り替えました。それ以来、私はずっと苦労しなくなった。過去にインテントベースのアプローチで私が抱えていた問題は、おそらく私自身の能力不足でした。

あなたが本当にこのルートに行く必要がある場合、Android 4.0+。

19
Ralf

アプローチ2の問題は安定性です。いくつかの例を試しましたが、一部のデバイスでカメラが機能しないように(再起動するまで)停止し、別のデバイスを完全にフリーズしました。別のデバイスではキャプチャは機能しましたが、プレビューは黒のままでした。

例にバグがあるか、デバイスとの互換性の問題があります。

9
CommonsWare

CommonsWareの例はうまく機能します。この例はそのまま使用すると機能しますが、使用例に合わせて変更したときに発生した問題は次のとおりです。

  1. 最初の写真が完了する前、つまりPictureCallback.onPictureTaken()が呼び出される前に、2番目の写真を撮らないでください。 CommonsWareの例では、この目的でinPreviewフラグを使用しています。
  2. SurfaceViewがフルスクリーンであることを確認してください。小さいプレビューが必要な場合は、プレビューサイズの選択ロジックを変更する必要がある場合があります。そうしないと、一部のデバイスでは、プレビューがSurfaceViewに収まらない場合があります。一部のデバイスは全画面のプレビューサイズのみをサポートしているため、全画面を維持することが最も簡単なソリューションです。

プレビュー画面により多くのコンポーネントを追加するために、私の経験ではFrameLayoutはうまく機能します。 LinearLayoutを使用してプレビューの上にテキストを追加することから始めましたが、それはルール#2に違反しています。 FrameLayoutを使用してプレビューの上にコンポーネントを追加する場合、プレビューの解像度に問題はありません。

GitHubCamera.open()に関するマイナーな問題も投稿しました。

1
Ralf

"カメラにアクセスするための推奨される方法は、別のスレッドでカメラを開くことです" 。そうでない場合、 Camera.open() は時間がかかり、UIスレッドの処理速度が遅くなる可能性があります。

"コールバックは、open(int)が呼び出されたイベントスレッドで呼び出されます" 。そのため、カメラプレビューコールバックを使用して最高のパフォーマンスを実現するには(たとえば、ライブコミュニケーション用に低レイテンシビデオにエンコードするため)、次に示すように、新しいHandlerThreadでカメラを開くことをお勧めします here

0
Alex Cohn