Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture image from custom CameraView in Android?

try to use Surface View for creating dynamic camera view and set in your required portion.

following code try

variables set Class level (Global)

Button btn_capture;
Camera camera1;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
public static boolean previewing = false;

Following code in onCreate() method

getWindow().setFormat(PixelFormat.UNKNOWN);
    surfaceView = new SurfaceView(this);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
btn_capture = (Button) findViewById(R.id.button1);

surfaceView.setBackgroundResource(R.drawable.your_background_image);

if(!previewing){

        camera1 = Camera.open();
        if (camera1 != null){
            try {
                camera1.setDisplayOrientation(90);
                camera1.setPreviewDisplay(surfaceHolder);
                camera1.startPreview();
                previewing = true;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

btn_capture.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub

            if(camera != null)
            {
                camera1.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG);

            }
        }
    });

Following code put after onCreate() in your class.

ShutterCallback myShutterCallback = new ShutterCallback(){

    public void onShutter() {
        // TODO Auto-generated method stub
    }};

PictureCallback myPictureCallback_RAW = new PictureCallback(){

    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub
    }};

PictureCallback myPictureCallback_JPG = new PictureCallback(){

    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub
        Bitmap bitmapPicture = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);

        Bitmap correctBmp = Bitmap.createBitmap(bitmapPicture, 0, 0, bitmapPicture.getWidth(), bitmapPicture.getHeight(), null, true);

    }};

public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    // TODO Auto-generated method stub
    if(previewing){
        camera1.stopPreview();
        previewing = false;
    }

    if (camera1 != null){
        try {
            camera1.setPreviewDisplay(surfaceHolder);
            camera1.startPreview();
            previewing = true;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub

}

public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub

        camera1.stopPreview();
        camera1.release();
        camera1 = null;
        previewing = false;

}

in AndroidManifest.xml give user-permissions.

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>

and also not forgot ( implements SurfaceHolder.Callback ) to the class.


I already created like that kind of Camera. What I did is, I covered the other area of the camera with an image, and cut the center part of the image and save it as png file, to make the center transparent.

You will set background image of your frame(camera preview) with that image. So that it will look like the camera is only that portion that is transparent or the circle.

I used this tutorial to open,create preview,and take picture from camera device http://developer.android.com/guide/topics/media/camera.html

in this part(u can see this in the link I provide above)

 private PictureCallback mPicture = new PictureCallback() {

 @Override
 public void onPictureTaken(byte[] data, Camera camera) {
   //this is where you crop your image
    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inMutable = true;
    Bitmap bitmap = BitmapFactory
            .decodeByteArray(data, 0, data.length, opt);

    bitmap=Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
    Canvas mcanvas=new Canvas(bitmap);
    //do the cropping here, bitmap is the image you will use to crop

  }

 }

follow this tutorial on how to crop the image to circle Cropping circular area from bitmap in Android


you can use surface view.after capture image u can get in bitmap and draw canvas also

http://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas)

http://developer.android.com/reference/android/view/SurfaceView.html#setZOrderMediaOverlay(boolean)


If the part of the screen is actually a view, you can capture only this view. Like this:

Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(),Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);

If you want to capture only small portion of a view, you have to calculate rectangle of this side. Then:

Bitmap bitmap = Bitmap.createBitmap(rect.width(),rect.height(),Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.save();
canvas.translate(-rect.left,-rect.top);
view.draw(canvas);
canvas.restore();

It's only a pseudocode, but I hope you get the idea. Simply translate and draw only the part you need.


I use the CameraPreview in ApiDemos application and edit it as your requirement.

First, copy the code of the Preview class into a new class file in the same package so that it is public and you can declare it in the xml layout file. Remember to add one more constructor as below:

public Preview(Context context, AttributeSet attrs) {
    super(context, attrs);
    mSurfaceView = new SurfaceView(context);
    addView(mSurfaceView);

    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

Sample layout file with sample width and height:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Abow"/>

   <com.example.android.apis.graphics.Preview
       android:id="@+id/camera_view"
       android:layout_width="240dp"
       android:layout_height="180dp">
   </com.example.android.apis.graphics.Preview>     

   <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Below"/>

</LinearLayout>

In the onCreate() method of the CameraPreview activity, change the setContentView part as followed:

setContentView(R.layout.camera_layout);
mPreview = (Preview) findViewById(R.id.camera_view);

use TextureView for preview,set layout_width and layout_height what ever you want. here is the code:

public class MainActivity extends Activity implements TextureView.SurfaceTextureListener {
    private Camera mCamera;
    private TextureView mTextureView;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mTextureView = (TextureView) findViewById(R.id.textureView);
        mTextureView.setSurfaceTextureListener(this);
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
        mCamera = Camera.open();

        try {
            mCamera.setPreviewTexture(surfaceTexture);
            mCamera.setDisplayOrientation(90);
            mCamera.startPreview();
        } catch (IOException exception) {

        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        mCamera.startPreview();
        mCamera.release();
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
        //To change body of implemented methods use File | Settings | File Templates.
    }
}

and xml file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <TextureView
        android:layout_gravity="center"
        android:id="@+id/textureView"
        android:layout_width="200dp"
        android:layout_height="300dp"/>
</LinearLayout>