Original address: http://blog.csdn.net/yanzi1225627/article/details/8605061#
Many times, the Android camera module not only previews, take pictures so simple, but need to preview the video, can make some detection, such as the most common face detection. Before the camera button is pressed, the face is detected and the rectangle is marked, followed by the photo. So how do I get a preview frame video?
You just have to inherit the Previewcallback interface in the activity . Examples are as follows:
public class Rectphoto extends Activity implements Surfaceholder.callback, previewcallback{}. (Note that this surfaceholder.callback is used to preview the webcam video, see my front stickers).
After inheriting this method, the function is automatically overloaded: public void Onpreviewframe (byte[] data, Camera camera) {} The data in this function is the real-time preview frame video . is automatically called. There are three ways to call Previewcallback, you can refer to this, there are three ways to call this callback. A callback is a function that automatically triggers a call when the condition is met. The difference is:. setpreviewcallback , , setpreviewcallbackwithbuffer , I generally use the second method.
As explained here, if the activity inherits the Previewcallback interface, just Camera.setoneshotpreviewcallback (this); The program automatically invokes the Onpreviewframe function in the main class activity . If the Camera.setoneshotpreviewcallback () function is inside the main class activity, such as Class A, The parameters inside should be written as Camera.setoneshotpreviewcallback (Youractivity.this). Of course here, you can also define a variable, such as Camera.previewcallback Mpreviewcallback, Use Camera.setoneshotpreviewcallback (mpreviewcallback) to complete the call. I believe a lot of people are familiar with this, so I will not wordy.
Just write your handler in the Onpreviewframe () function. When you do not usually do this, because the algorithm that handles real-time preview frame video can be complex, it requires asynctask to open a thread to process the data in the background. This assumes that we define a facetask for human face detection, which can be written like this:
/*custom Facetask class to open a thread profiling data*/ Private classFacetaskextendsAsynctask<void, Void, void>{ Private byte[] mdata; //constructor FunctionPalmtask (byte[] data) { This. Mdata =data; } @Overrideprotectedvoid Doinbackground (void ... params) {//TODO auto-generated Method StubSize size = Mycamera.getparameters (). Getpreviewsize ();//Get preview Size Final intW = size.width;//width Final inth =Size.Height; FinalYuvimage image =NewYuvimage (Mdata, Imageformat.nv21, W, H,NULL); Bytearrayoutputstream OS=NewBytearrayoutputstream (mdata.length); if(!image.compresstojpeg (NewRect (0, 0, W, h), 100, OS)) { return NULL; } byte[] tmp =Os.tobytearray (); Bitmap bmp = Bitmapfactory.decodebytearray (tmp, 0, tmp.length); dosomethingneeded (BMP); //self-defined algorithm for real-time analysis preview frame video return NULL; } }
Note that the BMP above is the real-time preview frame data in the bitmap format. dosomethingneeded (BMP) is what you want to do with the preview frame video, which can be used to detect faces or other, such as analyzing whether there is a fire. or the transmission. In addition, this is done by Yuvimage and imageformat.nv21 to parse the data. On Huawei U9200, the android4.0.3 system works well. The formats supported on different phones may vary. Online also have their own write algorithms for conversion, need to find their own, but here if the support of this format does not have to write their own conversion algorithm.
onpreviewframe () can write in this way:/*Get preview Frame video*/ Public voidOnpreviewframe (byte[] data, camera camera) { //TODO auto-generated Method Stub if(NULL!=mfacetask) { Switch(Mfacetask.getstatus ()) { CaseRUNNING:return; CasePENDING:mFaceTask.cancel (false); Break; }} mfacetask=Newpalmtask (data); Mfacetask.execute (Void)NULL); }
The mfacetask above is a global variable. Through the comprehensive application of onpreviewframe,asynctask, so that complex processing algorithms executed in the background, that is , Doinbackground here, is not greener?
Next is when to trigger Onpreviewframe () in this function, it can be triggered by a button once, in the key to listen to write Mycamera.setoneshotpreviewcallback (rectphoto.this); is automatically triggered once. Some people say they want to focus first and then analyze the preview frame. Write the callback in the Onautofocus. As follows:
//Auto Focus Variable callbackMyautofocuscallback =NewAutofocuscallback () { Public voidOnautofocus (Booleansuccess, Camera camera) { //TODO auto-generated Method Stub if(success)//success indicates successful focus{log.i (tag,"Myautofocuscallback:success ..."); Mycamera.setoneshotpreviewcallback (Rectphoto. This); } Else { //No focus succeededlog.i (Tag,"Myautofocuscallback: Failed ..."); //This can also add Mycamera.autofocus (myautofocuscallback), if focus fails, start focusing again. } } };
Most of the time, you want the program to automatically check the preview frame automatically every few hours. This is done, as follows:
classScanthreadImplementsrunnable{ Public voidrun () {//TODO auto-generated Method Stub while(!Thread.CurrentThread (). isinterrupted ()) { Try { if(NULL! = Mycamera &&Ispreview) { //Mycamera.autofocus (myautofocuscallback);Mycamera.setoneshotpreviewcallback (Rectphoto. This); LOG.I (Tag,"Setoneshotpreview ..."); } thread.sleep (1500); } Catch(interruptedexception e) {//TODO auto-generated Catch blockE.printstacktrace (); Thread.CurrentThread (). interrupt (); } } } }
In OnCreate new Thread (new Scanthread ()). Start () to open the scan thread. If you want to manually trigger the abort of this scan activity, you can set the flag bit in the while loop in the Scanthread, depending on my previous blog post.
Finally, if Previewcallback is added to the program, it is best to perform mycamera.setoneshotpreviewcallback (null) when Surfacedestroy releases the camera; or mycamera.setpreviewcallback (null); aborting this callback and then releasing the camera is more secure. Failure to do so may cause an error.