33

カメラのプレビューを全画面表示するための小さなアプリケーションを開発しました。これには Camera API を使用しています。

アクティビティのレイアウトは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <!-- This is the container for the camera preview screen -->
    <FrameLayout android:id="@+id/camera_preview"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"/>
</LinearLayout>

デバイスが縦向きの場合、ディスプレイはデバイス画面の高さに合わせて縦方向にスケーリングされるため、縦横比はネイティブ カメラのものと同じではありません。これらは、私が言っていることをよりよく説明する2つの画像です。

ここに画像の説明を入力ここに画像の説明を入力

最初の画像は、ネイティブのカメラ デバイスで作成されています。2 番目の画像は、私のアプリでカメラを全画面表示にして作成したものです。

getSupportedPreviewSizes()メソッドで指定されたプレビューサイズに関係なく、歪みなく、カメラのプレビューを全画面表示にする必要があります。これを達成する方法はありますか?カメラのプレビューが全画面表示のときに適切な縦横比を維持する方法はありますか? これはOSによって自動的に行われると思っていました-アスペクト比を維持しながら、要求された解像度に合わせて画像をトリミングしましたが、これは起こりません。

ディスプレイよりも大きくしようとしましたSurfaceView(この質問に従って:ディスプレイよりも大きい SurfaceView にカメラ プレビューを合わせる) が、スナップショット (6 フレーム/秒) をキャプチャしているため、私の場合は問題ありません。ユーザーが画面に表示するものではありません (フレームには、すべてが画面に表示されていなくても、すべてのカメラ プレビューが含まれます)。

ここに投稿しました: https://www.dropbox.com/s/3d52xt8kazynsae/CameraFullScreen.7z?v=0mcn私が作成したプロジェクト全体。

アイデア/解決策は、私にとって何よりも重要です。どうもありがとう。

================================================== ======================

ss1271 回答による更新:

上で書いたSamsung Galaxy Ace IIの解像度を少し分析します。

I. 画面解像度: 480x800 - アスペクト比 3:5 = 0,6

Ⅱ.getSupportedPreviewSizes- これらの値はバック カメラからのものであるとほぼ確信しています。以下は、これらの解像度のアスペクト比です。

   2560x1920   - 0,75

   2560x1536   - 0,60

   2048x1536   - 0,75

   2048x1232   - 0,60

   960x720     - 0,75

   640x480     - 0,75

したがって、メソッドは2560x1536または2048x1232Sizeに対応する を返します。これらは画面解像度と同じ縦横比を持ち、これらの値を使用しても画像は歪みません。私にとっての問題は、1 秒あたり 6 フレームをキャプチャし、これらをより低い解像度で保存する必要があるため、それほど大きな解像度を使用できないことです。

以下に、 Samsung S2デバイスの結果をいくつか示します。

I. 画面解像度: 480 x 800 - アスペクト比 3:5 = 0,6

Ⅱ.バックカメラ
a)。getSupportedPreviewSizes:

800 / 480   - 480/800 = 0,60
800 / 450   - 450/800 = 0,56
720 / 480   - 0,66 
640 / 480   - 0,75
352 / 288   - 0,81
320 / 240   - 0,75
176 / 144   - 0,81

b)。ネイティブ カメラ解像度:

3264 / 2448  - 0,75  - not full screen
3264 / 1968  - 0,60  - FULL SCREEN (since has the same aspect ratio as device screen)
2048 / 1536  - 0,75  - not full screen
2048 / 1232  - 0,60  - FULL SCREEN (same aspect ratio as device screen)
800 / 480    - 0,60  - FULL SCREEN (same aspect ratio as device screen)
640 / 480    - 0, 75 - not full screen

III. フロントカメラ
a)。getSupportedPreviewSizes:

640 / 480   - 0,75
352 / 288   - 0,81
320 / 240   - 0,75
176 / 144   - 0,81

b)。ネイティブ カメラが全画面表示ではなく、解像度を選択できません。オプションが無効になっています。

getSupportedPreviewSizes()S2、バックカメラの場合、メソッドがネイティブカメラと同じ解像度を返さないのはなぜですか、またはネイティブカメラによって表示されるものは画像サイズですか? getSupportedPreviewSizes()メソッドで指定された 3264 / 1968、2048 / 1232 などのオプションがないのはなぜですか? : ここに画像の説明を入力

4

2 に答える 2

28

簡単に言えば、フルスクリーンでカメラのプレビューを行うことができますが、カスタマイズされたカメラのプレビューが必要な場合にのみ、サポートされているプレビュー サイズの中から適切なサイズを自分で見つける必要があります。

あなたの質問については、Android Developers -- Cameraによると

カメラ プレビューに特定のサイズを設定する場合は、surfaceChanged()上記のコメントに記載されている方法でこれを設定します。プレビュー サイズを設定するときは、 の値を使用 する必要getSupportedPreviewSizes()があります。メソッドに任意の値を設定しないでくださいsetPreviewSize()

によって提供されるサイズ以外に、必要なサイズを手動で渡すことはできないようですgetSupportedPreviewSizes()。携帯電話のカメラでサポートされているサイズを詳しく調べると、サポートされているサイズの比率が画面の比率と正確に一致しない場合があることがわかります。

たとえば、Samsung Galaxy Ace II の解像度は 480x800 の画面で、Sizeから返された を読み取ることでgetSupportedPreviewSizes()、そのカメラは以下をサポートします。

2560x1920

2560x1536

2048x1536

2048x1232

960×720

640×480

また、カメラ プレビューをフル スクリーンで正しく (ストレッチなしで) 表示したい場合は、これらのサポートされているプレビュー サイズで適切な比率を計算、比較、適用する必要があります。

適切なプレビュー サイズを見つける実装はそれほど複雑ではありません。これを行うための一般的な方法は、次のようなものです。

    /**
     * Calculate the optimal size of camera preview
     * @param sizes
     * @param w
     * @param h
     * @return
     */
    private Size getOptimalSize(List<Size> sizes, int w, int h) {

        final double ASPECT_TOLERANCE = 0.2;        
        double targetRatio = (double) w / h;         
        if (sizes == null)             
            return null;          
        Size optimalSize = null;         
        double minDiff = Double.MAX_VALUE;          
        int targetHeight = h;          
        // Try to find an size match aspect ratio and size         
        for (Size size : sizes) 
        {             
//          Log.d("CameraActivity", "Checking size " + size.width + "w " + size.height + "h");            
            double ratio = (double) size.width / size.height;            
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)                
                continue;             
            if (Math.abs(size.height - targetHeight) < minDiff) 
            {                 
                optimalSize = size;                 
                minDiff = Math.abs(size.height - targetHeight);             
            }         
        }          
        // Cannot find the one match the aspect ratio, ignore the requirement     

        if (optimalSize == null)
        {
            minDiff = Double.MAX_VALUE;             
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff)
                {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight); 
                }
            }
        }

        SharedPreferences previewSizePref;
        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            previewSizePref = getSharedPreferences("PREVIEW_PREF",MODE_PRIVATE);
        } else {
            previewSizePref = getSharedPreferences("FRONT_PREVIEW_PREF",MODE_PRIVATE);
        }

        SharedPreferences.Editor prefEditor = previewSizePref.edit();
        prefEditor.putInt("width", optimalSize.width);
        prefEditor.putInt("height", optimalSize.height);

        prefEditor.commit();

//      Log.d("CameraActivity", "Using size: " + optimalSize.width + "w " + optimalSize.height + "h");            
        return optimalSize;     
    }

また、同様の操作を行って、適切なカメラ サイズ (出力画像サイズ) を見つけることもできます。

注: 上記のコードの元のバージョンをインターネットから見つけ、自分の目的のためにいくつかの変更/最適化を行いました。

これがうまくいくかどうか教えてください。

于 2013-05-24T10:57:41.197 に答える