OpenCVのAndroidカメラのサンプルコードに戸惑っています。SurfaceHolder.Callback
彼らは、メソッド内に次の行を実装して配置するカスタムクラスを作成しsurfaceChanged
ます。
mCamera.setPreviewDisplay(null);
のAndroidドキュメントのsetPreviewDisplay
説明:
このメソッドは、startPreview()の前に呼び出す必要があります。唯一の例外は、startPreview()が呼び出される前にプレビューサーフェスが設定されていない(またはnullに設定されていない)場合、このメソッドをnull以外のパラメーターで1回呼び出して、プレビューサーフェスを設定できることです。(これにより、カメラのセットアップとサーフェスの作成を並行して実行できるため、時間を節約できます。)プレビューの実行中は、プレビューサーフェスが変更されない場合があります。
異常なことに、OpenCVのコードはsetPreviewDisplay
null以外のSurfaceHolderで呼び出すことはありません。正常に動作しますが、を使用して画像の回転を変更しても動作しsetDisplayOrientation
ません。この行がなくても同じ結果が得られるため、この行も何も実行していないように見えます。
の代わりにsetPreviewDisplay
SurfaceHolderを指定して呼び出すと、画像は回転しますが、画像処理の結果は含まれません。後で電話するときにも受け取ります。surfaceChanged
null
IllegalArgumentException
lockCanvas
どうしたの?
これは、コードの(おそらく)最も関連性の高い部分であり、わずかに簡略化され、メソッドがインライン化されています。これがフルバージョンです。
クラス定義
public abstract class SampleViewBase extends SurfaceView
implements SurfaceHolder.Callback, Runnable {
カメラを開いたとき
mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
synchronized (SampleViewBase.this) {
System.arraycopy(data, 0, mFrame, 0, data.length);
SampleViewBase.this.notify();
}
camera.addCallbackBuffer(mBuffer);
}
});
表面が変化したとき
/* Now allocate the buffer */
mBuffer = new byte[size];
/* The buffer where the current frame will be copied */
mFrame = new byte [size];
mCamera.addCallbackBuffer(mBuffer);
try {
mCamera.setPreviewDisplay(null);
} catch (IOException e) {
Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
}
[...]
/* Now we can start a preview */
mCamera.startPreview();
runメソッド
public void run() {
mThreadRun = true;
Log.i(TAG, "Starting processing thread");
while (mThreadRun) {
Bitmap bmp = null;
synchronized (this) {
try {
this.wait();
bmp = processFrame(mFrame);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (bmp != null) {
Canvas canvas = mHolder.lockCanvas();
if (canvas != null) {
canvas.drawBitmap(bmp, (canvas.getWidth() - getFrameWidth()) / 2,
(canvas.getHeight() - getFrameHeight()) / 2, null);
mHolder.unlockCanvasAndPost(canvas);
}
}
}
Log.i(TAG, "Finishing processing thread");
}