How to capture image from custom CameraView in Android?

27,020

Solution 1

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

Solution 2

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)

Solution 3

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);

Solution 4

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>

Solution 5

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.

Share:
27,020
Mr.Sandy
Author by

Mr.Sandy

Sr.Android developer in TruKKer Technologies pvt. ltd. Knowledge Related to iPhone/iPod/iPad. Android/Tablet, J2ME, Blackberry, Honeycomb. Web Service, XML, JSON, RSS, SOAP, WSDL, REST Push Notification for iPhone &amp; Android &amp; Blackberry. In-App purchase &amp; In-app Billing. Social Media Integration Mapping functions In-App Purchase many more...

Updated on September 29, 2020

Comments

  • Mr.Sandy
    Mr.Sandy over 3 years

    i need to capture image from required portion of the screen.

    capture image from camera.

    at that time other screen content as it is.

    enter image description here

    how is this possible?

  • Mr.Sandy
    Mr.Sandy about 11 years
    i think you know this @Zielony, but you can not perfectly understand my requirements. please told me how can i set camera in this portion only from my full screen ? and capture image from that. after that bitmap and canvas used to draw and store image for other use.
  • Zielony
    Zielony about 11 years
    If you only need a part of the picture captured from the camera, you can simply crop the image. Capture the picture: stackoverflow.com/questions/5991319/… and then crop it using Bitmap.createBitmap with x,y,width,height parameters.
  • Mr.Sandy
    Mr.Sandy about 11 years
    no..no..i not need to crop image but i need when i open camera it is not open in full screen but only open in portion of the screen which is set for that. same as above image.
  • MH.
    MH. almost 11 years
    Where it's worth noting that TextureView wasn't introduced until ICS (API level 14).
  • user2234
    user2234 over 6 years
    But this solutions wouldn't work if a face is to be detected and auto captured, as it could be out of the circular area