setPreviewDisplay(null)が正常に表示されない問題について
7036 ワード
「Android NDK Beginner Guide」では4章でJavaでJNIを呼び出すCコードをセグメントルーチンで示し,JNI Cコードを用いてYUV 420からRGB 888に独自に変換する過程をCameraViewクラスで実証したが,実際にはこのコードはシミュレータでは問題なく,多くの実機では表示できない.
海外サイトでは一般的にAndroid 3.0以降のバージョンではCAmeraオブジェクトのsetPreviewDisplayはnullをパラメータとして使用できません.そうしないとonPreviewFrameコールバック関数は呼び出されません.このヒントを押して修正すると、画面に2つのプレビューパターンが表示され、絵の中の絵のような効果があり、小さな画面はonPreviewFrame->OnDrawで呼び出されます.大きいのはsetPreviewDisplayバインドの現在のSurface Viewが自動的にリフレッシュされます.皆さんはまだもっと良い解決策があるかどうか分かりません.
海外サイトでは一般的にAndroid 3.0以降のバージョンではCAmeraオブジェクトのsetPreviewDisplayはnullをパラメータとして使用できません.そうしないとonPreviewFrameコールバック関数は呼び出されません.このヒントを押して修正すると、画面に2つのプレビューパターンが表示され、絵の中の絵のような効果があり、小さな画面はonPreviewFrame->OnDrawで呼び出されます.大きいのはsetPreviewDisplayバインドの現在のSurface Viewが自動的にリフレッシュされます.皆さんはまだもっと良い解決策があるかどうか分かりません.
public class CameraView extends SurfaceView
implements SurfaceHolder.Callback, Camera.PreviewCallback
{
static {
System.loadLibrary("livaCamera");
}
public static final String TAG = "CameraView";
public native void decode(Bitmap pTarget, byte[] pSource);
private Camera mCamera;
private byte[] mVideoSource;
private Bitmap mBackBuffer;
private Paint mPaint;
public CameraView(Context context) {
super(context);
getHolder().addCallback(this);
setWillNotDraw(false);
}
public void surfaceCreated(SurfaceHolder holder) {
Log.v(TAG, "surfaceCreated()");
try {
mCamera = Camera.open();
mCamera.setDisplayOrientation(0);
// mCamera.setPreviewDisplay(null); // SurfaceHolder
mCamera.setPreviewDisplay(this.getHolder()); //null
mCamera.setPreviewCallbackWithBuffer(this); Log.d(TAG, "surfaceCreated() startPreview Success ");
} catch (Exception e) {
mCamera.release();
mCamera = null;
throw new IllegalStateException();
}
}
public void surfaceChanged(SurfaceHolder pHolder,
int pFormat,
int pWidth,
int pHeight)
{
Log.v(TAG, "surfaceChanged()");
try {
mCamera.stopPreview();
Log.d(TAG, "surfaceChanged() stopPreview Success ");
} catch (Exception e){
// ignore: tried to stop a non-existent preview
Log.d(TAG, "surfaceChanged() stopPreview Failed ");
}
Size lSize = findBestResolution(pWidth, pHeight);
PixelFormat lPixelFormat = new PixelFormat();
PixelFormat.getPixelFormatInfo(
mCamera.getParameters().getPreviewFormat(),
lPixelFormat);
int lSourceSize = lSize.width * lSize.height * lPixelFormat.bitsPerPixel / 8;
if( mVideoSource == null )
{
mVideoSource = new byte[lSourceSize];
}
if( mBackBuffer == null )
{
mBackBuffer = Bitmap.createBitmap(lSize.width, lSize.height,Bitmap.Config.ARGB_8888);
}
Camera.Parameters lParameters = mCamera.getParameters();
lParameters.setPreviewSize(lSize.width, lSize.height);
lParameters.setPreviewFormat(ImageFormat.NV21); // PixelFormat.YCbCr_422_I deprecated in API level 8.
mCamera.setParameters(lParameters);
mCamera.addCallbackBuffer(mVideoSource);
try {
//mCamera.setPreviewDisplay(null);
mCamera.startPreview();
Log.d(TAG, "surfaceChanged() startPreview Success ");
} catch (Exception e){
// ignore: tried to stop a non-existent preview
Log.d(TAG, "surfaceChanged() startPreview Failed ");
}
}
private Size findBestResolution(int pWidth, int pHeight)
{
List<Size> lSizes = mCamera.getParameters().getSupportedPreviewSizes();
Size lSelectedSize = mCamera.new Size(0, 0);
for (Size lSize : lSizes) {
if ((lSize.width <= pWidth)
&& (lSize.height <= pHeight)
&& (lSize.width >= lSelectedSize.width)
&& (lSize.height >= lSelectedSize.height)) {
lSelectedSize = lSize;
}
}
if ((lSelectedSize.width == 0)
|| (lSelectedSize.height == 0)) {
lSelectedSize = lSizes.get(0);
}
return lSelectedSize;
}
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.v(TAG, "surfaceDestroyed()");
if (mCamera != null) {
mCamera.stopPreview();
try {
mCamera.reconnect();
} catch (IOException e) {
e.printStackTrace();
}
mCamera.release();
mCamera = null;
mVideoSource = null;
mBackBuffer = null;
}
}
public void onPreviewFrame(byte[] pData, Camera pCamera)
{
int[] px = new int[100];
Log.v(TAG, "onPreviewFrame()");
decode(mBackBuffer, pData);
mFrameCnt++;
invalidate();
}
@Override
protected void onDraw(Canvas pCanvas)
{
Log.v(TAG, "onDraw()");
if (mCamera != null) {
pCanvas.drawBitmap(mBackBuffer, 0, 0, mPaint);
mCamera.addCallbackBuffer(mVideoSource);
}
}
}