canvas drawBitmap不显示相机预览

时间:2013-12-28 05:09:52

标签: android camera android-canvas preview drawbitmap

我无法使用canvas.drawbitmap在我的Android屏幕上显示相机预览。屏幕全黑,我验证了drawtext方法正常工作。请让我知道我做错了什么!!

class CameraView extends SurfaceView implements
            SurfaceHolder.Callback, Camera.PreviewCallback {
static {
    System.loadLibrary("canvasdraw");
}

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

    // Registers current class so that it listens to surface
    // event (creation, destruction and changes).
    getHolder().addCallback(this);
    // Clears the flag keeping the surface from getting drawn.
    // Necessary when not drawing from a thread.
    setWillNotDraw(false);
}

public void surfaceCreated(SurfaceHolder holder) {
    try {
        // Acquires the default camera.
       // mCamera = Camera.open();

        try {
            mCamera = Camera.open(0);
        } catch (RuntimeException e) {
            Log.e("CameraTest", "Camera Open filed");
            return;
        }
        // Sets landscape mode to avoid complications related to
        // screen orientation handling.
        mCamera.setDisplayOrientation(0);
        // Registers callbacks. Automatic preview is deactivated
        // as we want to process data ourself (in a buffer).
        mCamera.setPreviewDisplay(null);
        mCamera.setPreviewCallbackWithBuffer(this);
    } catch (IOException eIOException) {
        mCamera.release();
        mCamera = null;
        throw new IllegalStateException();
    }
}

public void surfaceChanged(SurfaceHolder pHolder, int pFormat,
                int pWidth, int pHeight) {
    mCamera.stopPreview();

    // Finds a suitable resolution.
    Size lSize = findBestResolution(pWidth, pHeight);

    // Prepares video source and back buffers.
    PixelFormat lPixelFormat = new PixelFormat();
    PixelFormat.getPixelFormatInfo(mCamera.getParameters()
                    .getPreviewFormat(), lPixelFormat);
    int lSourceSize = lSize.width * lSize.height
                    * lPixelFormat.bitsPerPixel / 8;
    mVideoSource = new byte[lSourceSize];
    mBackBuffer = Bitmap.createBitmap(lSize.width, lSize.height,
                    Bitmap.Config.ARGB_8888);

    // Set-up camera size and video format. YCbCr_420_SP
    // should be the default on Android anyway.
    Camera.Parameters lParameters = mCamera.getParameters();
    lParameters.setPreviewSize(lSize.width, lSize.height);
    lParameters.setPreviewFormat(PixelFormat.YCbCr_420_SP);
    mCamera.setParameters(lParameters);

    // Starts receiving pictures from the camera.
    mCamera.addCallbackBuffer(mVideoSource);
    mCamera.startPreview();
}

private Size findBestResolution(int pWidth, int pHeight) {
    List<Size> lSizes = mCamera.getParameters()
                    .getSupportedPreviewSizes();
    // Finds the biggest resolution which fits the screen.
    // Else, returns the first resolution found.
    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;
        }
    }
    // Previous code assume that there is a preview size smaller
    // than screen size. If not, hopefully the Android API
    // guarantees that at least one preview size is available.
    if ((lSelectedSize.width == 0)
                    || (lSelectedSize.height == 0)) {
        lSelectedSize = lSizes.get(0);
    }
    return lSelectedSize;
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Releases camera which is a shared resource.
    if (mCamera != null) {
        mCamera.stopPreview();
        mCamera.release();
        // These variables can take a lot of memory. Gets rid of
        // them as fast as we can.
        mCamera = null;
        mVideoSource = null;
        mBackBuffer = null;
    }
}

public void onPreviewFrame(byte[] pData, Camera pCamera) {
    // New data has been received from camera. Processes it and
    // requests surface to be redrawn right after.
    decode(mBackBuffer, pData);
    invalidate();
}

@Override
protected void onDraw(Canvas pCanvas) {
    if (mCamera != null) {

      //  Paint textPaint = new Paint();
     //   textPaint.setARGB(255, 200, 0, 0);
     //   textPaint.setTextSize(60);

    //    pCanvas.drawText("Hello World!", 50, 50, textPaint);

     // Draws resulting image at screen origin.
        pCanvas.drawBitmap(mBackBuffer, 0, 0, null);
        // Enqueues buffer again to get next image.
        mCamera.addCallbackBuffer(mVideoSource);
    }
}
}

1 个答案:

答案 0 :(得分:0)

当您将预览显示设置为 null ,或者为其提供假表面时,相机预览将不起作用。在某些设备上,系统可能存在错误,并且使用偷偷摸摸的变通方法可以启动预览帧获取,而无需在屏幕上显示预览。

但也许出于您的目的,setPreviewTexture()将完成这项工作。