我想创建一个增强现实应用程序。我对 android 很陌生,我刚刚开始研究我的项目。为了热身,我想开发一个分析二维码并显示适当图像的应用程序。我做了一项研究,发现论坛代码正在做我想做的类似事情。我对其进行了更改以完全符合我的需求,并且它不想工作。我得到了相机预览,但没有图像覆盖在上面。在错误日志中,我得到“未处理的事件循环异常”。我正在附加我的 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