In this Android tutorial we will launch the Camera and display an image in the CameraView. We will use the following Android programming concepts:
- SurfaceView and SurfaceHolder to set the CameraView as part of our MainActivity
- Seperate overlay.xml to set the image which we wan to display in the CameraView.
First we create 2 layout files (1) the layout which holds the SurfaceView and (2) the layout which hold the image we want to display.
Open you Activity_Main.xml and set a SurfaceView as a child of your LinearLayout.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <SurfaceView android:id="@+id/cameraview" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
Secondly create a new layout in your resources folder and name it overlay.xml and simple add an ImageView in this layout. This ImageView will hold the image your want to display in your CameraView.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="bottom"> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@drawable/ringimage" /> </LinearLayout>
Now you have set your layout, you can open the MainActivity.java.
- We set the MainActivity to our layout (Activity_Main.xml) and set the ScreenLayout to Horizontal.
- Create a SurfaceView and set it to your cameraview which you created in your Activity_Main layout.
- Implement the SurfaceHolder which holds this cameraviev
Next we need to inflate the Image we set in our overlay.xml.
- Call the LayoutInflater
- Set your LayoutInflater to your image (in my case overlay.xml which holds the ImageView)
- Set some LayoutInflater parameters
Finally we need to set what we want the camera to do in the standard Android SDK methods of the SurfaceView (surfaceCreated, surfaceChanged, surfaceDestroyed).
package com.christianpeeters.ghost; import java.io.IOException; import android.app.Activity; import android.content.pm.ActivityInfo; import android.graphics.PixelFormat; import android.hardware.Camera; import android.os.Bundle; import android.view.LayoutInflater; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup.LayoutParams; public class MainActivity extends Activity implements SurfaceHolder.Callback{ Camera camera; SurfaceView surfaceView; SurfaceHolder surfaceHolder; boolean cameraview = false; LayoutInflater inflater = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); getWindow().setFormat(PixelFormat.UNKNOWN); surfaceView = (SurfaceView)findViewById(R.id.cameraview); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); inflater = LayoutInflater.from(getBaseContext()); View view = inflater.inflate(R.layout.overlay, null); LayoutParams layoutParamsControl= new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); this.addContentView(view, layoutParamsControl); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub if(cameraview){ camera.stopPreview(); cameraview = false; } if (camera != null){ try { camera.setPreviewDisplay(surfaceHolder); camera.startPreview(); cameraview = true; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub camera = Camera.open(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub camera.stopPreview(); camera.release(); camera = null; cameraview = false; } }
Christian,
Any reason I’m getting a black screen with my image instead of the camera & the ability to take a picture?
Thanks,
Tim
Hi Tim, sorry for my late reply. It’s hard to tell. Did you try to copy past my complete code?
before “this.addContentView(view, layoutParamsControl);” add view.setVisibility(View.GONE)
Camera is active but it’s behind new view that’s added
Hi, i already do this, but when i add a button to take a picture it doesnt put the image in the photo, do you know what do i have to do to take the picture and that the image appear on the photo
Best regards
thank’s bro :D
#good Tutorial :)
Thanks a lot for breaking down the code in easily understandable manner !!
hi ,
can any one tell me how to create an camera application which capture only the selected area in the screen i.e a rectangle should be placed in screen to select the object .
plz giude me
nice dude help full
It’s very helpful and easy to understand. Thanks
Hi Christian. Great, easy to understand tutorials.
I tried copying your code and I copied my image into the drawable folders with the name “ringimage.png” but now I get errors “Missing content description on attribute image” for the ImageView and “The method setType(int) from the type SurfaceHolder is deprecated”. How do I fix this?
Update: I fixed the Missing content description by adding one to strings.xml
Hey could you help me?
How can i adjust contrast, saturation, color hue in live camera at real time before taking picture programmatically. if anyone have any idea please help me.
Hey Christian is it possible to overlay a video instead of a image? If yes please tell me how to do