AR Android在相机预览的每一帧上叠加图像

时间:2013-08-06 19:36:42

标签: android camera augmented-reality preview

我想创建一个增强现实应用。我对android很新,我刚刚开始研究我的项目。为了热身,我想开发一个分析QR码并显示适当图像的应用程序。我做了一项研究,我在论坛代码上发现了我想要做的类似事情。我改变它以完全符合我的需要,它不想工作。我得到了相机预览,但没有覆盖图像。在错误日志中,我得到“Unhandeled event loop exception”。我正在附加我的CameraPreview类和CameraActivity类。 在此先感谢您的帮助。

    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback,Camera.PreviewCallback {

   public SurfaceHolder mHolder;
   public Camera mCamera;
   public Parameters parameters;
   public Size size;
   private int[] decodedCameraPreview;
   public Bitmap bitmap;
   private int width;
   private int height;
   private boolean isPreviewRunning = false;
   private Canvas canvas;

    private static final String TAG = "CameraPreview";

    public CameraPreview(Context context, AttributeSet attrs) {
        super(context,attrs);

        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

    public void surfaceCreated(SurfaceHolder holder) {

         synchronized (this) {
         if (isPreviewRunning)
             return;

            setWillNotDraw(false);

            mCamera = getCameraInstance();
            isPreviewRunning = true;

            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
                mCamera.setPreviewCallback(this);

                parameters = mCamera.getParameters();  
                size = parameters.getPreviewSize();  
                decodedCameraPreview = new int[size.width * size.height];
                width = size.width;
                height = size.height;                   

            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
            }
        }
    }

    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open();
        }
        catch (Exception e){
        }
        return c;
    }



    public void onPreviewFrame(byte[] data, Camera camera) {

         if(!isPreviewRunning)
                return;

         canvas = null;


        if(mHolder == null){
            return;
        }

        try {
            synchronized (mHolder) {

                canvas = mHolder.lockCanvas();

                int canvasWidth = canvas.getWidth();
                int canvasHeight = canvas.getHeight();

                decodeYUV(decodedCameraPreview, data, width, height);// data is      in YUV format, this function converts them to RGB bitmap

    // analyze QR code 


                canvas.drawBitmap(decodedCameraPreview, 0, width, canvasWidth-((width+canvasWidth)>>1), canvasHeight-((height+canvasHeight)>>1), width, height, false, null);
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.star); // for example draw an image of a star          
                canvas.drawBitmap(bitmap, (canvas.getWidth()/2), (canvas.getHeight()/2), null);


            }
        }catch(Exception e){
            e.printStackTrace();

            }
         finally {
            if (canvas != null) {
                mHolder.unlockCanvasAndPost(canvas);
            }
        }
    }

    public void decodeYUV(int[] out, byte[] fg, int width, int height) throws NullPointerException, IllegalArgumentException {
        int sz = width * height;
        if (out == null)
            throw new NullPointerException("buffer out is null");
        if (out.length < sz)
            throw new IllegalArgumentException("buffer out size " + out.length + " < minimum " + sz);
        if (fg == null)
            throw new NullPointerException("buffer 'fg' is null");
        if (fg.length < sz)
            throw new IllegalArgumentException("buffer fg size " + fg.length + " < minimum " + sz * 3 / 2);
        int i, j;
        int Y, Cr = 0, Cb = 0;
        for (j = 0; j < height; j++) {
            int pixPtr = j * width;
            final int jDiv2 = j >> 1;
        for (i = 0; i < width; i++) {
            Y = fg[pixPtr];
            if (Y < 0)
                Y += 255;
            if ((i & 0x1) != 1) {
                final int cOff = sz + jDiv2 * width + (i >> 1) * 2;
                Cb = fg[cOff];
                if (Cb < 0)
                    Cb += 127;
                else
                    Cb -= 128;
                Cr = fg[cOff + 1];
                if (Cr < 0)
                    Cr += 127;
                else
                    Cr -= 128;
            }
            int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
            if (R < 0)
                R = 0;
            else if (R > 255)
                R = 255;
            int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
            if (G < 0)
                G = 0;
            else if (G > 255)
                G = 255;
            int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
            if (B < 0)
                B = 0;
            else if (B > 255)
                B = 255;
            out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R;
        }}
        }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
            int arg3) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        synchronized (this) {
            try {
                if (mCamera != null) {
                    mHolder.removeCallback(this);
                    mCamera.setPreviewCallback(null);
                    mCamera.stopPreview();
                    isPreviewRunning  = false;
                    mCamera.release();
                }
            } catch (Exception e) {
                Log.e("Camera", e.getMessage());
            }
        }
    }
    }

相机活动:

    public class CameraActivity extends Activity {

private static final String TAG = "CameraActivity";
private Camera mCamera;
public DrawPreview drawPreview;
public RelativeLayout relativeLayout;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera_preview);

    relativeLayout = (RelativeLayout)findViewById(R.id.svCmeraActivity);                  
    SurfaceView surfaceView = new CameraPreview(this, null);
    relativeLayout.addView(surfaceView);      
}

protected void onPause() {
    super.onPause();      
    releaseCamera();  
}

 @Override
protected void onResume() {
    super.onResume();
}

private void releaseCamera(){
        if (mCamera != null){
            mCamera.release(); 
            mCamera = null;
        }
    }

}

错误日志:

Wed Aug 07 21:07:05 CEST 2013 未处理的事件循环异常

    org.eclipse.swt.SWTException: Failed to execute runnable (java.lang.NullPointerException)
at org.eclipse.swt.SWT.error(SWT.java:4361)
at org.eclipse.swt.SWT.error(SWT.java:4276)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:138)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4144)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3761)
at         org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1053)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:942)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:588)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:543)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
    Caused by: java.lang.NullPointerException
at com.android.ddmuilib.logcat.LogCatPanel.deviceSelected(LogCatPanel.java:364)
at com.android.ddmuilib.SelectionDependentPanel.deviceSelected(SelectionDependentPanel.java:52)
at com.android.ide.eclipse.ddms.views.SelectionDependentViewPart.selectionChanged(SelectionDependentViewPart.java:69)
at com.android.ide.eclipse.ddms.LogCatMonitor$4.run(LogCatMonitor.java:217)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
... 24 more

0 个答案:

没有答案