Before the project involves some camera preview and data processing operations, the demand is in addition to do the camera preview, but also to display text, personality images, and so on, when looking for data to implement the relevant modules, found that a lot of information about the more cumbersome, not concise, here will own the way to share the realization, I hope to provide some ideas for the students who are doing the relevant work. But here first by the way, if you simply do the camera preview, do not preview the data when adding text, images and other additional operations, you can use the Surfaceview way, performance will be better.
Here the camera capture and video image is placed in a module, relatively easy to manage and maintain, while in use, because the class inherits from the view class, so you can manipulate many view classes, add it to any layout, and the data collected at a high proportion of the width of the premise of consistency, The view size can be controlled very flexibly on the page display. But using this way to achieve camera preview, the biggest bottleneck is in the rotation of YUV data and convert it to RGB data, the calculation is more time-consuming, generally the acquisition of 640*480 data is OK, but for 960*720 data, mobile phone performance generally, will appear to compare cards. Solution in the data rotation, you can try to use the NDK C way to improve the efficiency of operation, in the YUV to RGB, you can also try to use the NDK C way, but the best way is to use the GPU shader way, directly render YUV data, The captured YUV data is uploaded to the GPU in a textured fashion, and then the GPU completes the YUV RGB and displays it. Here is the relevant code:
public class Cameraview extends View implements previewcallback{//source video frame width/height private int srcframewidth = 640;private int src frameheight = 480;private int framesize = srcframewidth * srcframeheight;private int qtrframesize = srcFrameWidth * SrcFra Meheight >> 2;//Frame preview Map private Bitmap previewbmp = null;private Rect previewrect = null;private camera camera = null; Layer Private baselayer[] layers = null;//data acquisition private int[] Rgb_data = null;private byte[] yuvdata = null;//Camera Front/rear publi C static final int camera_back = 0;public static final int camera_front = 1;private int curcameraindex = CAMERA_BACK;PUBL IC Cameraview (Context _context) {super (_context);} Public Cameraview (Context _context, AttributeSet _attrs) {super (_context, _attrs);} Public Cameraview (context context, int previewwidth, int previewheight, int cameraindex) {super (context); Curcameraindex = Cameraindex;rgb_data = new Int[framesize];yuvdata = new byte[framesize * 3/2];p reviewbmp = Bitmap.createbitmap (srcFram Eheight, SrcframewIdth, config.argb_8888);p reviewrect = new Rect (0, 0, previewwidth, previewheight);//define layer layers = new Baselayer[2];layers [0] = new Textlayer (context, 0, false); layers[1] = new Imagelayer (context, 1, false);//Text ((Textlayer) layers[0]). SETFONTP Arams (Color.cyan);((Textlayer) layers[0]). Settextpos (+);((Textlayer) layers[0]). SetContent ("nice weather ...") ; Layers[0].setvisible (true);//Image ((Imagelayer) layers[1]). Setimagepos (+); layers[1].setvisible (true);// Initialize and open the camera Startcamera (Cameraindex); This.setbackgroundcolor (Color.parsecolor ("#82858b"));} Initialize the camera according to the index public void Startcamera (int cameraindex) {//Stop the Camera Stopcamera () First,//Initialize and turn on the camera if (camera = = null) {camera = Cam Era.open (Cameraindex); Camera.parameters params = camera.getparameters ();p arams.setpreviewsize (Srcframewidth, srcframeheight); Params.setpreviewformat (IMAGEFORMAT.NV21); camera.setparameters (params); Camera.setpreviewcallback (this); Camera.startpreview ();}} Stop and release camera public void Stopcamera () {if (camera! = null) {CAMERA.SETPREVIEWCALlback (null); Camera.stoppreview (); camera.release (); camera = null;}} Draw @overrideprotected void OnDraw (canvas canvas) {super.ondraw (canvas);//Fill data (because the data has been rotated, the width and height need to be interchanged) Previewbmp.setpixels (rgb_data, 0, srcframeheight, 0, 0, srcframeheight, srcframewidth);//Draw a cartographic layer for (Baselayer Layer:laye RS) {if (layer.isvisible ()) {Layer.drawlayer (previewbmp);}} Map Canvas.drawbitmap (previewbmp, NULL, previewrect, NULL);} Get webcam video data @overridepublic void Onpreviewframe (byte[] data, camera camera) {int i = 0, j = 0, k = 0;int uvheight = Srcfram Eheight >> 1;//Rotate YUV data if (Curcameraindex = = Camera_back) {//rotate yfor (i = 0; i < srcframewidth; i++) {for (j = SrcF rameHeight-1; J >= 0; j--) {Yuvdata[k] = Data[srcframewidth * j + i];k++;}} Rotary uvfor (i = 0; i < srcframewidth; i + = 2) {for (j = uvHeight-1; J >= 0; j--) {Yuvdata[k] = Data[framesi Ze + srcframewidth * j + i + 1];//cb/u yuvdata[k + qtrframesize] = data[framesize + srcframewidth * j + i];//cr/v K + +; }}}else{//rotation yfor (i = SrcFrameWidth-1; I >= 0; i--) {for (j = srcFrameHeight-1; J >= 0; j--) {Yuvdata[k] = Data[srcframewidth * j + i];k++;}} Rotary uvfor (i = srcFrameWidth-2; I >= 0; I-= 2) {for (j = uvHeight-1; J >= 0; j--) {Yuvdata[k] = Data[fr Amesize + srcframewidth * j + i + 1];//cb/u yuvdata[k + qtrframesize] = data[framesize + srcframewidth * j + i];//cr/v k++; }}}//YUV to RGB (because the data has been rotated, at this time the width and height need to interchange) int YP = 0;for (i = 0, YP = 0; i < srcframewidth; i++) {int UVP = framesize + (i >& Gt 1) * uvheight, u = 0, v = 0;for (j = 0; J < Srcframeheight; J + +, yp++) {int y = (0xFF & Yuvdata[yp])-16;if ((J &am P 1) = = 0) {u = (0xFF & YUVDATA[UVP + (j>>1)])-128;v = (0xFF & YUVDATA[UVP + qtrframesize + (j>>1)])- 128;} int y1192 = 1192 * Y;int r = (y1192 + 1634 * v), int g = (y1192-833 * v-400 * u), int b = (y1192 + 2066 * u), if (R < 0) r = 0; else if (R > 262143) r = 262143;if (G < 0) g = 0; else if (g > 262143) g = 262143;if (b < 0) B = 0; else if (b > 262143) b = 262143;rgb_data[i*srcframeheight + j] = 0xff000000 | (r << 6) & 0xff0000) | ((G >> 2) & 0xff00) | ((b >>) & 0xff);} for}//forinvalidate ();}}Project Download Link: http://download.csdn.net/detail/u013085897/8652979
Camera data acquisition and display in Android environment