android - Can I use lockCanvas() in onPreviewFrame callback? -
i'm fighting illegalargumentexception when using lockcanvas() in onpreviewframe.
basically want achieve grab frame, process it, , draw directly surface of surfacepreview.
here code of onpreviewframe
@override public void onpreviewframe(byte[] data, camera camera) { canvas canvas = null; if (mholder == null) { return; } int mimgformat = mcamera.getparameters().getpreviewformat(); try { canvas = mholder.lockcanvas(); canvas.drawcolor(0, android.graphics.porterduff.mode.clear); mholder.unlockcanvasandpost(canvas); } catch (exception e) { e.printstacktrace(); } { if (canvas != null) { mholder.unlockcanvasandpost(canvas); } } }
i have read lot of documentation , topics camera in android, , suppose locking surface frames drawn onto isn't possible, because it's beyond scope of application control. true?
one of possible solutions draw on top of surface view view, want keep processed frames (there canny edge detection , color corrections, may time consuming) drawn in sync preview. when camera keep spitting frames fps calculations have hard time catching up, , in worst case scenario draw overlay dozens of frames behind.
i studied opencv source , me looks they've managed in camerabridgeviewbase.java:
protected void deliveranddrawframe(cvcameraviewframe frame) { mat modified; if (mlistener != null) { modified = mlistener.oncameraframe(frame); } else { modified = frame.rgba(); } boolean bmpvalid = true; if (modified != null) { try { utils.mattobitmap(modified, mcachebitmap); } catch(exception e) { log.e(tag, "mat type: " + modified); log.e(tag, "bitmap type: " + mcachebitmap.getwidth() + "*" + mcachebitmap.getheight()); log.e(tag, "utils.mattobitmap() throws exception: " + e.getmessage()); bmpvalid = false; } } if (bmpvalid && mcachebitmap != null) { canvas canvas = getholder().lockcanvas(); if (canvas != null) { canvas.drawcolor(0, android.graphics.porterduff.mode.clear); canvas.drawbitmap(mcachebitmap, (canvas.getwidth() - mcachebitmap.getwidth()) / 2, (canvas.getheight() - mcachebitmap.getheight()) / 2, null); if (mfpsmeter != null) { mfpsmeter.measure(); mfpsmeter.draw(canvas, 20, 30); } getholder().unlockcanvasandpost(canvas); } } }
i'm either missing or i'm old :)
also, it's first post here hello :)
actually, opencv's camera plays little trick. in camerabridgeviewbase.java , javacameraview.java file. found surfacetexture class(from api 11) used receive frames camera. advantage of surfacetexture not need draw on screen(it can contained in memory). surfaceview class responsible draw processed frame onpreviewframe function. note surfaceview not bound camera. hope can help.
Comments
Post a Comment