Play to Android Camera Development (ii): Preview camera Base photo demo using Textureview and Surfacetexture

Source: Internet
Author: User

Google since Android4.0 out of the Textureview, why launch it? is to make up for surfaceview deficiencies, on the other hand is to balance glsurfaceview, of course, this is my speculate. About the relationship between Textureview, Surfaceview, Surfacetexture, Glsurfaceview, we will launch the Glsurfaceview preview camera after our special analysis. This article focuses on previewing a camera using Textureview.

In fact, on how to preview the camera with Textureview, the official website has given the demo, see here. In addition, link 1 Link 2 also gives a complete preview of the camera's demo, but it's all a bunch of things dyed in one piece. This article uses a lightweight camera frame built in the previous article to quickly replace the Surfaceview. Because use Surfaceview preview words to pass a surfaceholder in, with Textureview preview words need to pass in a surfacetexture. Other camera processes are the same.

First, the new Cameratextureview class inherits the Textureview, and implements the Textureview.surfacetexturelistener interface. Implementing this interface is like implementing Surfaceholder.callback, the main purpose is to know when Surfacetexture is ready, that is, onsurfacetextureavailable this function.

Cameratextureview.java

Package Org.yanzi.camera.preview;import Org.yanzi.camera.camerainterface;import Android.content.context;import Android.graphics.pixelformat;import Android.graphics.surfacetexture;import Android.util.attributeset;import Android.util.log;import Android.view.surfaceholder;import Android.view.surfaceview;import Android.view.textureview;public class Cameratextureview extends Textureview implements Textureview.surfacetexturelistener {private static final String TAG = "Yanzi"; Context Mcontext; Surfacetexture Msurface;public Cameratextureview (context context, AttributeSet Attrs) {Super (context, attrs);//TODO auto-generated constructor Stubmcontext = Context;this.setsurfacetexturelistener (this);} @Overridepublic void onsurfacetextureavailable (surfacetexture surface, int width,int height) {//TODO auto-generated Method Stublog.i (TAG, "onsurfacetextureavailable ..."); msurface = Surface;//camerainterface.getinstance (). Dostartpreview (surface, 1.33f);} @Overridepublic Boolean onsurfacetexturedestroyed (Surfacetexture surface) {//TODO auto-generated method stublog.i (TAG, "onsurfacetexturedestroyed ..."); Camerainterface.getinstance (). Dostopcamera (); return true;} @Overridepublic void onsurfacetexturesizechanged (surfacetexture surface, int width,int height) {//TODO auto-generated Method Stublog.i (TAG, "onsurfacetexturesizechanged ...");} @Overridepublic void onsurfacetextureupdated (Surfacetexture surface) {//TODO auto-generated method stublog.i (TAG, " Onsurfacetextureupdated ... "); /* Allow activity to get textureview surfacetexture * @see android.view.textureview#getsurfacetexture () */public Surfacetexture _getsurfacetexture () {return msurface;}}
second, in the layout of the file to add it, because his father is the view, as a general view of the line

<relativelayout xmlns:android= "http:// Schemas.android.com/apk/res/android "xmlns:tools=" Http://schemas.android.com/tools "android:layout_width=" Match_ Parent "android:layout_height=" Match_parent "tools:context=". Cameraactivity "> <framelayout android:layout_width=" wrap_content "android:layout_height=" Wrap_cont            Ent "> <org.yanzi.camera.preview.cameratextureview android:id=" @+id/camera_textureview "        Android:layout_width= "0dip" android:layout_height= "0dip"/> </FrameLayout> <imagebutton        Android:id= "@+id/btn_shutter" android:layout_width= "wrap_content" android:layout_height= "Wrap_content" android:background= "@drawable/btn_shutter_background" android:layout_alignparentbottom= "true" android:l Ayout_centerhorizontal= "true" android:layout_marginbottom= "10dip"/></RELATIVELAYOUT>  

Three, in Camerainterface, I encapsulated two functions:

/** use Surfaceview to open Preview * @param holder * @param previewrate */public void Dostartpreview (Surfaceholder holder, float Previe Wrate) {log.i (TAG, "Dostartpreview ..."); if (ispreviewing) {Mcamera.stoppreview (); return;} if (Mcamera! = null) {try {mcamera.setpreviewdisplay (holder);} catch (IOException e) {//TODO auto-generated catch BLOCKE.P Rintstacktrace ();} Initcamera (previewrate);}}  /** using Textureview Preview camera * @param surface * @param previewrate */public void Dostartpreview (surfacetexture surface, float Previewrate) {log.i (TAG, "Dostartpreview ..."); if (ispreviewing) {Mcamera.stoppreview (); return;} if (Mcamera! = null) {try {mcamera.setpreviewtexture (surface)} catch (IOException e) {//TODO auto-generated catch Blocke. Printstacktrace ();} Initcamera (previewrate);}}  
corresponds to Surfaceview and Textureview previews respectively. You can see that the arguments passed in are different, Initcamera () are the same thing.

private void Initcamera (float previewrate) {if (Mcamera! = null) {Mparams = Mcamera.getparameters (); Mparams.setpictureformat (pixelformat.jpeg);//Set the picture format stored after the photo//camparautil.getinstance (). Printsupportpicturesize ( Mparams);//camparautil.getinstance (). Printsupportpreviewsize (Mparams);//Set previewsize and Picturesizesize Picturesize = Camparautil.getinstance (). Getproppicturesize (Mparams.getsupportedpicturesizes (), PreviewRate, 800); Mparams.setpicturesize (Picturesize.width, picturesize.height); Size previewsize = Camparautil.getinstance (). Getproppreviewsize (Mparams.getsupportedpreviewsizes (), PreviewRate, Mparams.setpreviewsize (Previewsize.width, previewsize.height); Mcamera.setdisplayorientation (90);// Camparautil.getinstance (). Printsupportfocusmode (Mparams); list<string> focusmodes = Mparams.getsupportedfocusmodes (), if (Focusmodes.contains ("Continuous-video")) { Mparams.setfocusmode (Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);} Mcamera.setparameters (Mparams); Mcamera.startpreview ();//Open Preview IspreviEwing = True;mpreviwrate = Previewrate;mparams = Mcamera.getparameters (); Re-get once log.i (TAG, "final settings: Previewsize--with =" + mparams.getpreviewsize (). width+ "Height =" + mparams.getpreviewsize () . height); LOG.I (TAG, "final settings: Picturesize--with =" + mparams.getpicturesize (). width+ "height =" + mparams.getpicturesize (). height);} }

Four, in the activity, still open a thread to open Camera:

Thread openthread = new Thread () {@Overridepublic void Run () {//TODO auto-generated method Stubcamerainterface.getinstanc E (). Doopencamera (cameraactivity.this);}};o Penthread.start ();

Preview in the camera open callback:

@Overridepublic void camerahasopened () {//TODO auto-generated method Stubsurfacetexture surface = Textureview._ Getsurfacetexture (); Camerainterface.getinstance (). Dostartpreview (surface, previewrate);}

After that, you can see that the camera changes with the previous Surfaceview preview are very small.


Several caveats:

1, Textureview is the Android 4.0 after the addition of the lower version of this class. Textureview must work in an environment where hardware acceleration is enabled, in the settings of the activity in the configuration file: Android:hardwareaccelerated= "True" is the default property, so no more writing is required. But if you write false, you can see Onsurfacetextureavailable () This callback will not come in, Textureview no surfacetexture also play a fart ah.

2. The normal log for the demo to open camera and preview is:

Line 417:06-22 12:37:43.682 I/yanzi (4917): Camera open .... Line 489:06-22 12:37:43.758 I/yanzi (4917): Onsurfacetextureavailable ... Line 533:06-22 12:37:43.819 I/yanzi (4917): Camera open over .... Line 535:06-22 12:37:43.819 I/yanzi (4917): Dostartpreview ... Line 537:06-22 12:37:43.825 I/yanzi (4917): picturesize:w = 1280h = 720Line 539:06-22 12:37:43.825 I/yanzi (4917 ): Previewsize:w = 800h = 448Line 555:06-22 12:37:43.874 i/yanzi (4917): Final setting: Previewsize--with = 800Height = 448Line   557:06-22 12:37:43.874 I/yanzi (4917): Final setting: Picturesize--with = 1280Height = 720Line 577:06-22 12:37:44.106 I/yanzi (4917): onsurfacetextureupdated ... Line 579:06-22 12:37:44.138 I/yanzi (4917): onsurfacetextureupdated ... Line 583:06-22 12:37:44.169 I/yanzi (4917): onsurfacetextureupdated ... Line 585:06-22 12:37:44.220 I/yanzi (4917): onsurfacetextureupdated ... Line 587:06-22 12:37:44.253 I/yanzi (4917): onsurfacetextureupdated ...

Test Phone for ZTE Geek, this mobile phone camera is very good, than the hand of Huawei G700 Strong, is occasionally not even on camera Service, Khan. As you can see from log, onsurfacetextureavailable This callback takes some time. Camera.open () This sentence used more than 130 Ms. But two points are different from Surfaceview. First, Textureview is not entered into the onsurfacetexturesizechanged () function during the creation process. and Surfaceview in the creation process, from scratch into the size of changes in the callback. Second, onsurfacetextureupdated () This function comes in one frame of data each time . This is one of the greatest places compared to Surfaceview. Through this interface, you can send the surfacetexture to OpenGL to deal with. This callback is real-time, not a 2-time callback using the camera's previewcallback. From the time, basically every 32ms or so on a frame of data, that is, 30 frames per second, with the phone's camera performance match.

3, the camera to perform startpreview must ensure that the Textureview surfacetexture up, if for some performance reasons onsurfacetextureavailable () This callback does not come on the preview, It's not going to open. If this happens, open and startpreview operations are performed in the Onsurfacetextureavailable () callback to ensure foolproof.

4, Textureview itself has getsurfacetexture () This function, I also encapsulated a:

/* Allow activity to get textureview surfacetexture * @see android.view.textureview#getsurfacetexture () */public Surfacetexture _getsurfacetexture () {return msurface;}
The msurface here is the surfacetexture in the Onsurfacetextureavailable () callback. Test proof, direct adjustment when opening preview

Textureview.getsurfacetexture (), pass it to Camera:mCamera.setPreviewTexture (surface), and you can preview it normally. But it is recommended to use the former for the following official words:

A Textureview ' s surfacetexture can be obtained either by invokinggetSurfaceTexture()or by using aTextureView.SurfaceTextureListener. It is important to know that a surfacetexture are available only after the Textureview are attached to a window ( andonAttachedToWindow()Has been invoked.) It is therefore highly recommended your use of a listener to being notified when the surfacetexture becomes available.

Two ways to get surfacetexture, the recommended use of monitoring. Because only when the Textureview executes the Onattachedtowindow, its tsurfacetexture comes up.

5. Relationship between Surfacetexture and Textureview:

surfacetexture . the  Surfacetexture  can then being used to render content

textureview is a painting, that surfacetexture is the canvas, the real rendering of the carrier is surfacetexture;

6, textureview can perform various changes like the general view, which has a textureview.setalpha (1.0f), which is not written by default, and its alpha is 1.0f, which is opaque. If set to transparent 0.0f, you can see nothing, this is just the opposite of Surfaceview. surfaceview" Surfaceholder is generally set to transparent is transparent. But textureview because it is a view, the transparency of any PNG photo is set to 0 and must not be seen.

7, if think preview a camera this is Textureview and surfacetexture mission, it is wrong, the real intention is to seamlessly connect with OpenGL.

--------------------This article is original, reproduced please specify the author yanzi1225627

Version number: Playcamera_v2.0.0[2014-6-22].zip

csdn Download Link: http://download.csdn.net/detail/yanzi1225627/7540903

Baidu Cloud Disk:



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.