だから私はカメラアプリに似たものに取り組んでいます。ネイティブの OpenGL テクスチャにライブ カメラ プレビューを描画します。ボタンを押すと、静止画像が生の形式でキャプチャされます (ライブ プレビューよりも高い解像度である可能性があります)。
これが私のコードの一般的な概要です。わかりやすくするために、関連性の低い部分は表示していません。これは、プレビューと静止画の解像度が同じである単純化された状況です。
void Setup(Activity a) {
// .. snip ..
mSurfaceView = new SurfaceView(a);
mSurfaceView.getHolder().addCallback(this);
//put the surface off-screen
AbsoluteLayout.LayoutParams alp = new AbsoluteLayout.LayoutParams(8, 8, -8, -8);
a.addContentView(mSurfaceView, alp); //need this, otherwise surface is not created
mCamera = Camera.open(miCameraId);
mCamera.setPreviewCallbackWithBuffer(this);
ConfigureCameraDefaults(640,480);
}
// -------------------------------------------------------------------- //
void ConfigureCameraDefaults(int iX, int iY) {
Camera.Parameters oParameters=mCamera.getParameters();
oParameters.setPreviewFormat(ImageFormat.NV21);
oParameters.setPictureFormat(ImageFormat.NV21);
oParameters.setPreviewSize(iX, iY); // for live preview
oParameters.setPictureSize(iX, iY); // for still capture
int bpp = ImageFormat.getBitsPerPixel(ImageFormat.NV21);
int iBufSize = (int) (iX*iY*((float)bpp/8));
mBuffer = new byte[iBufSize];
mCamera.addCallbackBuffer(mBuffer);
try {
mCamera.setParameters(oParameters);
} catch (Exception e) {
// .. snip ..
}
}
void startPreview() {
mCamera.startPreview();
}
void stopPreview() {
mCamera.stopPreview();
}
void takePicture() {
mCamera.takePicture(null, this, null, null); //2nd is the raw callback
}
// -------------------------------------------------------------------- //
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// -- at this point the buffer is in a safe state, until it is added again
onPreviewFrame_native(data);
// -- make buffer writable again
mCamera.addCallbackBuffer(mBuffer);
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
onStillCapture_native(data);
mCamera.startPreview(); //otherwise preview will stop
}
では、質問です。が呼び出されない場合takePicture()
、すべてが計画どおりに機能します。プレビュー フレームが到着し、処理され、バッファが再キューイングされます。ただし、startPreview()
その後にするtakePicture()
と、ピクチャ コールバックは null データ配列を取得します。毎回。Googleドキュメントには、これについて次のように書かれていtakePicture()
ます:
The raw callback occurs when the raw image data is available (NOTE: the data will be
null if there is no raw image callback buffer available or the raw image callback
buffer is not large enough to hold the raw image).
次のように、これは私には完全には明らかではありません。
- 静止キャプチャ用のバッファを設定する機能はありません。前のフレームのみです。
- 静止画とプレビュー フレームの両方に同じバッファーが使用されている場合でも、バッファーがキューに入れられます。
- 静止画用に 2 番目のバッファー (プレビュー バッファーと同じ) を追加しても、まったく効果がありません
takePicture()
を有効な呼び出しにするためには、プレビューを開始する必要があります。
明らかな何かが欠けていますか?それとも、ビデオから生のフレームを取得することは許可されていませんか? これに関するドキュメントには何もありません。カメラのソースも見ましたが、役に立ちませんでした。
どんな助けでも大歓迎です。
PS。写真を撮る前にプレビュー コールバックを設定解除し、2 番目のバッファーを追加し、2 番目のバッファーを再度キューに入れ、サーフェス ホルダーをプッシュ タイプに設定し、その他いくつかのことを試してみましたが、一瞬。どれも違いはありませんでした。