19

次のようなアクティビティを書きたいと思います。

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

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


これまでの私の研究:

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

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

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

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

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

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


アップデート:

しばらくの間、私はカメラAPIを直接使用しました。これにより、より詳細な制御(カスタムUIなど)が可能になりますが、誰にもお勧めしません。私はデバイスの90%で作業しますが、新しいデバイスがリリースされることがあり、別の問題が発生します。

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

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

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

本当にこのルートに行く必要がある場合は、Android4.0以降のデバイスのみをサポートする方がはるかに簡単だと聞いています。

4

3 に答える 3

9

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

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

于 2011-12-09T20:27:11.633 に答える
1

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

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

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

Camera.open()また、GitHubに関連するマイナーな問題を投稿しました。

于 2011-12-10T12:29:13.310 に答える
0

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

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

于 2014-02-25T17:50:47.187 に答える