3

カメラプレビューを取り込んでピクセルを操作し、新しい画像を表示するカメラアプリを作成しようとしています。リアルタイムで操作を行う必要があります。

onPreviewFrame私がオンラインで読んだことと、ここでの質問から、カスタムサーフェスビューを作成し、メソッドからピクセル配列を操作する必要があります。カスタムサーフェスビューを作成し、このメソッドを実行しています。に変換しYUVましたRGB

さて、私の質問は、この新しいピクセル配列をリアルタイムで画面に表示するにはどうすればよいですか?onPreviewFrameどういうわけかメソッドで返しますか?byte[]アレイを変更する必要がありますか?新しいピクセル配列を取得し、ビットマップを使用して表示しますか?byte[]プレビューを表示せずにカメラプレビューからアレイを取得する方法はありますか?

誰かがこれらの質問に答えることができれば、コード例は素晴らしいでしょう!私はAndroidに慣れていないので、理解できるように十分に説明された答えが必要です。これが私が持っているカメラプレビューを実行するコードの一部です:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // start preview with new settings
        try {
            //parameters.setPreviewSize(w, h);
            mCamera.setParameters(parameters);
            mCamera.setPreviewDisplay(mHolder);
            mCamera.setPreviewCallback(new PreviewCallback() {
                public void onPreviewFrame(byte[] data, Camera camera)
                {
                    System.out.println("onPreviewFrame");
                    //transforms NV21 pixel data into RGB pixels  
                    decodeYUV420SP(pixels, data, previewSize.width,  previewSize.height);  

//Outuput the value of the top left pixel in the preview to LogCat  
                    Log.i("Pixels", "The top right pixel has the following RGB (hexadecimal) values:"  
                           +Integer.toHexString(pixels[0]));  


                }
            });
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(null, "Error starting camera preview: " + e.getMessage());
        }
    }

これにより、プレビューの代わりに表示したいrgbピクセル配列が得られます。どうすればよいですか?

4

1 に答える 1

1

カメラ プレビューに接続したサーフェスを操作することはできません。受け取るバイト配列onPreviewFrame()は、フレームワークが画面に表示するものの単なるコピーです。さらに、2 つのストリームが非同期であることがわかります。コールバックを遅くすることはできますが (たとえば、コールバックにいくつか追加することによってsleep())、それでもプレビュー サーフェスは更新されます。

他のビューをその上に配置してプレビューを非表示にするか、代わりに(注: API レベル 11 で追加SurfaceView)を使用してこのビューを完全に取り除くことができます。サーフェスを非表示にすることは、思ったほど簡単ではありません。フレームワークによって表面がポップアップする可能性があるため、カメラの開始または再起動をレイアウトと慎重に同期させる必要があります。setPreviewTexture()setPreviewDisplay()

とにかく、表面を非表示にした後、受け取ったバイト配列を使用しonPreviewFrame()て画像を生成し、表示できます。好みに合わせてピクセルを自由に操作できます。最適な手法は、ピクセル データを OpenGL に送信することだと思います。シェーダーを使用して、YCrCb (NV21) から RGB への変換を GPU にオフロードできます。

于 2012-11-25T08:07:51.153 に答える