2014-11-05 41 views
4

我想lockCanvas(),因为我想在预览前修改相机图片。我在onPreviewFrame上执行。onPreviewFrame和异常锁定表面

代码是在这里:

public class MyPreview implements Camera.PreviewCallback { 

     @Override 
     public void onPreviewFrame(byte[] data, Camera camera) { 
      Log.d("Camera", "Got a camera frame"); 

      Canvas c = null; 

      try { 
        c = mCamSH.lockCanvas(null); 

        Log.d("SOMETHING", "Got Bitmap"); 
      } finally { 
       if (c != null) { 
        mCamSH.unlockCanvasAndPost(c); 
       } 
      } 
     } 

    } //public class MyPreview implements Camera.PreviewCallback  

不幸的是我总是得到一个循环这个错误,问题是与C = mCamSH.lockCanvas(NULL); :

E/SurfaceHolder﹕ Exception locking surface 
    java.lang.IllegalArgumentException 
      at android.view.Surface.lockCanvasNative(Native Method) 
      at android.view.Surface.lockCanvas(Surface.java:76) 
      at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:831) 
      at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:811) 
      at cz.mrp.camera.CamActivity$MyPreview.onPreviewFrame(CamActivity.java:100) 
      at android.hardware.Camera$EventHandler.handleMessage(Camera.java:773) 
      at android.os.Handler.dispatchMessage(Handler.java:99) 
      at android.os.Looper.loop(Looper.java:137) 
      at android.app.ActivityThread.main(ActivityThread.java:4517) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:511) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760) 
      at dalvik.system.NativeStart.main(Native Method) 

整个代码是在这里:http://pastebin.com/WJs1kyfq

使用GT-S7562设备上的Android 4.0.4。

我已经尝试过在StackOverflow上搜索并使用谷歌,但没有找到任何可以帮助我的东西。感谢您的时间!

+0

我面临同样的问题,但它只发生在S8 /你是如何解决这个问题的? – 2017-08-07 11:17:58

回答

1

为什么使用

c = mCamSH.lockCanvas(null); 

试试这个:

c = mCamSH.lockCanvas(); 

@Edit 您试图呼吁mCamSH架lockCanvas。 但是,这个支架被相机使用,所以画布已经被它锁定。

要保持简短:我不认为你可以调用lockCanvas内onPreviewFrame

+0

感谢您的评论。不幸的是,这个问题仍然是一样的:(从lockCanvas中删除参数并没有帮助。 – Petr 2014-11-05 14:50:45

8

你不能做到这一点。

Surface不是缓冲区,它是生产者 - 消费者安排中的缓冲区队列。一次只能有一个制作人,这就是相机,所以你不能锁定Surface进行软件渲染。除非您的应用程序也是消费者,否则无法从Surface中读取数据,因此无法使用您当前的安排修改该框架。

解决这个问题的最有效方法取决于您要做什么。如果您只是想在预览中放置叠加层,则可以使用具有透明背景的自定义视图来完成此操作。如果您想在将图像保存为静止图像之前修改图像,那么在将其保存到磁盘之前,还要修改单个静帧。如果您想修改它以进行视频录制,则可以使用SurfaceTexture作为预览目标(这会在应用中为您提供生产者和消费者端),然后使用GLES修改图像。 Grafika中的“show + capture camera”活动演示了后者。

另请参阅Android System-Level Graphics Architecture文档。

2

我找到了解决方案。

您必须删除此代码,因为画布已被相机锁定。

mCam.setPreviewDisplay(mCamSH); 

为了显示相机预览,必须使用画布上的变量(byte [] data)手动绘制。

+0

在我的情况下,我无法删除该行,但是你的建议对我有很大帮助! – 2017-10-27 23:18:18