0

PreviewCallback インターフェイスを使用してカメラ ビデオの各フレームを読み取るためのサンプル コードまたは例を提供してもらえますか?

最初に画面に表示せずにカメラビデオのフレームが必要なため、サーフェスを使用せずにフレームを取得し、そのフレームを cocos2dx の CCLayer に渡すことができます。

4

1 に答える 1

1

これは処理が遅く、プレビュー コールバックに配信されたデータのすべてのフレームを処理できるわけではありません。これは、ライブ プレビュー アプリケーションの要件により、カメラからのビデオまたはカメラからのビデオをステンシルタイプのオーバーレイで表示することが不可能であり、ディスプレイが 1 秒あたり数フレームしか許容できず、ある程度の待ち時間がある場合にのみ使用してください。

いくつかの重要なステップ:

  1. アクティビティはサーフェス ホルダーを拡張する必要があり、サーフェスが作成されるまでカメラを起動しないでください。
  2. プレビューは、各デバイスで特定のサイズのみをサポートします (最後にチェックしたデバイスでは 480 x 320 - 少し前) ですが、あなたの要求は問題を引き起こさず、単に無視されます。最終的にプレビュー コールバックを受信したら、実際のフレーム サイズを で確認しonPreviewFrame()ます。
  3. に送信されるbyte[]配列データonPreviewFrame()は、YCbCr_422_SP 形式です。設定しようとしても、他の形式は使用できません。データはここで説明されています: http://groups.google.com/group/android-developers/msg/d3b29d3ddc8abf9b
  4. のデータをデコードしようとしないでくださいonPreviewFrame()。十分な時間がありません。その機能でシステムを長時間保持しようとすると、カメラにホースをかけます。データを独自のバッファにコピーし、別の .xml でデコードしますThread
  5. Thread 特定のフレームを処理している間は、受信した新しいフレームの処理をスキップする必要があります。が終了するまで待ってThreadから、次の利用可能なフレームからのデータを使用してください。

YUV プレビュー データをデコードします

// decode Y, U, and V values on the YUV 420 buffer 
// described as YCbCr_422_SP by Android - David Manpearl
public static void decodeYUV(int[] out, byte[] fg, int width, int 
height) throws NullPointerException, IllegalArgumentException { 
        final int sz = width * height; 
        if(out == null) throw new NullPointerException("buffer 'out' is null"); 
        if(out.length < sz) throw new IllegalArgumentException("buffer 'out' size " + out.length + " < minimum " + sz); 
        if(fg == null) throw new NullPointerException("buffer 'fg' is null"); 
        if(fg.length < sz) throw new IllegalArgumentException("buffer 'fg' size " + fg.length + " < minimum " + sz * 3/ 2); 
        int i, j; 
        int Y, Cr = 0, Cb = 0; 
        for(j = 0; j < height; j++) { 
                int pixPtr = j * width; 
                final int jDiv2 = j >> 1; 
                for(i = 0; i < width; i++) { 
                        Y = fg[pixPtr]; if(Y < 0) Y += 255; 
                        if((i & 0x1) != 1) { 
                                final int cOff = sz + jDiv2 * width + (i >> 1) * 2; 
                                Cb = fg[cOff]; 
                                if(Cb < 0) Cb += 127; else Cb -= 128; 
                                Cr = fg[cOff + 1]; 
                                if(Cr < 0) Cr += 127; else Cr -= 128; 
                        } 
                        int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); 
                        if(R < 0) R = 0; else if(R > 255) R = 255; 
                        int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5); 
                        if(G < 0) G = 0; else if(G > 255) G = 255; 
                        int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); 
                        if(B < 0) B = 0; else if(B > 255) B = 255; 
                        out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R; 
                } 
        } 
} 

byte[]配列を に変換Bitmap:

Bitmap bitmap = BitmapFactory.decodeByteArray(out , 0, out.length);
于 2013-04-01T06:30:42.170 に答える