您的位置:首页 > 编程语言 > PHP开发

关于 setPreviewDisplay(null) 无法正常显示的问题

2013-03-10 17:16 525 查看
    在 “Android NDK Beginner Guide”中第4章有段例程展示在Java中调用JNI的C代码,使用了CameraView类演示了用JNI C代码自己转换YUV420到RGB888的过程,但是实际这段代码在模拟器上倒是没问题,在很多实机上却无法显示。

    在国外网站上一般就说是 Android3.0后的版本中CAmera对象的setPreviewDisplay不能使用null作为参数,否则 onPreviewFrame 回调函数不会被调用。按这个提示修改后,将在界面上看到两个预览图案,类似画中画效果,小的画面是通过 onPreviewFrame -> OnDraw调用的。大的是setPreviewDisplay绑定当前SurfaceView自动刷新的。不知道大家还有没有更好的解决办法。

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);
}
}
}


    注意
















                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐