Skip to content Skip to sidebar Skip to footer

Camera.takepicture() Is Crashing My App

I have an app that is supposed to take pictures using the camera.takePicture. The code I use is the following : private Bitmap bitmapPicture; //inside onCreate btn.setOnClickListen

Solution 1:

Use this simple code to capture using the device camera

IMP Note: Add those permision to the mainfest file

<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permissionandroid:name="android.permission.CAMERA" />

The mainActivity

publicclassMainActivityextendsActivity {

privatestaticfinalintCAMERA_PIC_REQUEST=1111;//Constant ID for ActivityResultprivate ImageView mImage; // To display the thumbnail@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mImage = (ImageView) findViewById(R.id.camera_image);

    // Start an intent for Camera Capture with ResultActivityIntentcameraIntent=newIntent(
            android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);

}

@OverrideprotectedvoidonActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CAMERA_PIC_REQUEST) {
        // Get the image in a Bitmap extension to assign it to the ImageViewif (data.getExtras() == null)
            return;
        Bitmapthumb= (Bitmap) data.getExtras().get("data");
        mImage.setImageBitmap(thumb);

        // Compress the Bitmap image into JPEG to save it on the deviceByteArrayOutputStreambytes=newByteArrayOutputStream();
        thumb.compress(Bitmap.CompressFormat.JPEG, 100, bytes);// 100 is the scale..for less quality decrease the number                                // Save the image on the root SDCardFilefile=newFile(Environment.getExternalStorageDirectory()
                + File.separator + "imageName.png");

        try {
            // Create the file to save the image
            file.createNewFile();
            FileOutputStreamfo=newFileOutputStream(file);
            fo.write(bytes.toByteArray());
            fo.close();
        } catch (Exception e) {
        }

    }

}

}

Put This in your Layout MainActivity.XML :

    <ImageView android:id="@+id/camera_image"
    android:layout_width="wrap_content" android:layout_height="wrap_content" />

Solution 2:

I finally solved this . Below i give some code for anyone who wants to know how to take screenshots of a layout ,pictures from the camera without intent, screenshots(sort of) of the content of a surfaceView and save the screen shot in a folder :

publicclassCam_ViewextendsActivityimplementsSurfaceHolder.Callback{

protectedstaticfinalintCAPTURE_IMAGE_ACTIVITY_REQUEST_CODE=0;
private SurfaceView SurView;
private SurfaceHolder camHolder;
privateboolean previewRunning;
finalContextcontext=this;
publicstaticCameracamera=null;
private RelativeLayout CamView;
private Bitmap inputBMP=null,bmp,bmp1;
private ImageView mImage;




@SuppressWarnings("deprecation")@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera);

    CamView = (RelativeLayout) findViewById(R.id.camview);//RELATIVELAYOUT OR //ANY LAYOUT OF YOUR XML

    SurView = (SurfaceView)findViewById(R.id.sview);//SURFACEVIEW FOR THE PREVIEW //OF THE CAMERA FEED
    camHolder = SurView.getHolder();                           //NEEDED FOR THE PREVIEW
    camHolder.addCallback(this);                               //NEEDED FOR THE PREVIEW
    camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//NEEDED FOR THE PREVIEW
    camera_image = (ImageView) findViewById(R.id.camera_image);//NEEDED FOR THE PREVIEWButtonbtn= (Button) findViewById(R.id.button1); //THE BUTTON FOR TAKING PICTURE



    btn.setOnClickListener(newOnClickListener()     //THE BUTTON CODE
    {
        publicvoidonClick(View v)
        {
                  camera.takePicture(null, null, mPicture);//TAKING THE PICTURE//THE mPicture IS CALLED //WHICH IS THE LAST METHOD(SEE BELOW)
            }

        });

    }


@OverridepublicvoidsurfaceChanged(SurfaceHolder holder, int format, int width,//NEEDED FOR THE PREVIEW
    int height) {
if(previewRunning){
    camera.stopPreview();
}
Camera.ParameterscamParams= camera.getParameters();
Camera.Sizesize= camParams.getSupportedPreviewSizes().get(0); 
    camParams.setPreviewSize(size.width, size.height);
camera.setParameters(camParams);
try{
    camera.setPreviewDisplay(holder);
    camera.startPreview();
    previewRunning=true;
}catch(IOException e){
    e.printStackTrace();
}
}

publicvoidsurfaceCreated(SurfaceHolder holder) {                  //NEEDED FOR THE PREVIEWtry{
    camera=Camera.open();
}catch(Exception e){
    e.printStackTrace();
    Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
    finish();
}
}

@OverridepublicvoidsurfaceDestroyed(SurfaceHolder holder) {             //NEEDED FOR THE PREVIEW
camera.stopPreview();
camera.release();
camera=null;
}



publicvoidTakeScreenshot(){    //THIS METHOD TAKES A SCREENSHOT AND SAVES IT AS .jpgRandomnum=newRandom();
int nu=num.nextInt(1000); //PRODUCING A RANDOM NUMBER FOR FILE NAME
CamView.setDrawingCacheEnabled(true); //CamView OR THE NAME OF YOUR LAYOUR
CamView.buildDrawingCache(true);
Bitmapbmp= Bitmap.createBitmap(CamView.getDrawingCache());
CamView.setDrawingCacheEnabled(false); // clear drawing cacheByteArrayOutputStreambos=newByteArrayOutputStream(); 
                bmp.compress(CompressFormat.JPEG, 100, bos); 
                byte[] bitmapdata = bos.toByteArray();
                ByteArrayInputStreamfis=newByteArrayInputStream(bitmapdata);

                String picId=String.valueOf(nu);
                String myfile="Ghost"+picId+".jpeg";

                Filedir_image=newFile(Environment.getExternalStorageDirectory()+//<---
                        File.separator+"Ultimate Entity Detector");          //<---

                dir_image.mkdirs();                                                  //<---//^IN THESE 3 LINES YOU SET THE FOLDER PATH/NAME . HERE I CHOOSE TO SAVE//THE FILE IN THE SD CARD IN THE FOLDER "Ultimate Entity Detector"try {
                    FiletmpFile=newFile(dir_image,myfile); 
                    FileOutputStreamfos=newFileOutputStream(tmpFile);

                     byte[] buf = newbyte[1024];
                        int len;
                        while ((len = fis.read(buf)) > 0) {
                            fos.write(buf, 0, len);
                        }
                            fis.close();
                            fos.close();

                            Toast.makeText(getApplicationContext(),
                                    "The file is saved at :SD/Ultimate Entity Detector",Toast.LENGTH_LONG).show();

                            bmp1 = null;
                            camera_image.setImageBitmap(bmp1); //RESETING THE PREVIEW
                            camera.startPreview();             //RESETING THE PREVIEW       
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


}

privatePictureCallbackmPicture=newPictureCallback() {   //THIS METHOD AND THE METHOD BELOW//CONVERT THE CAPTURED IMAGE IN A JPG FILE AND SAVE IT@OverridepublicvoidonPictureTaken(byte[] data, Camera camera) {

    Filedir_image2=newFile(Environment.getExternalStorageDirectory()+
            File.separator+"Ultimate Entity Detector");
    dir_image2.mkdirs();  //AGAIN CHOOSING FOLDER FOR THE PICTURE(WHICH IS LIKE A SURFACEVIEW //SCREENSHOT)FiletmpFile=newFile(dir_image2,"TempGhost.jpg"); //MAKING A FILE IN THE PATH                 //dir_image2(SEE RIGHT ABOVE) AND NAMING IT "TempGhost.jpg" OR ANYTHING ELSEtry {//SAVINGFileOutputStreamfos=newFileOutputStream(tmpFile);
        fos.write(data);
        fos.close();
        //grabImage();
    } catch (FileNotFoundException e) {
        Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
    } catch (IOException e) {
        Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
    }

    Stringpath= (Environment.getExternalStorageDirectory()+  
            File.separator+"Ultimate EntityDetector"+
                                        File.separator+"TempGhost.jpg");//<---

    BitmapFactory.Optionsoptions=newBitmapFactory.Options();//<---
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;//<---
    bmp1 = BitmapFactory.decodeFile(path, options);//<---//THE LINES ABOVE READ THE FILE WE SAVED BEFORE AND CONVERT IT INTO A BitMap
    camera_image.setImageBitmap(bmp1); //SETTING THE BitMap AS IMAGE IN AN IMAGEVIEW(SOMETHING//LIKE A BACKGROUNG FOR THE LAYOUT)
    TakeScreenshot();//CALLING THIS METHOD TO TAKE A SCREENSHOT

}
};
 }

If you want to take a simple screenshot(no camera feed is needed) the you can use the TakeScreenshot method alone.

If you want to take a screenshot of a surfaceView with is not possible to do from the surfaceview directly the use the mPicture, set the picture you capture as backgroung , and then call TakeScreenshot to take your screenshot.(as seen above)

If you want to take a picture with the camera without calling an other camera app with an intent the use the takePicture with the mPicture and the surfaceView stuff from the code above.

What the previous code does if used "as is" is to take a screenshot of the layout contents(buttons,imageviews etc) and set as backgroung an image from the camera.

Below i also provide a basic layout xml for the previous code :

<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/camview"><SurfaceViewandroid:id="@+id/sview"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_alignParentLeft="true"android:layout_alignParentTop="true" /><ImageViewandroid:id="@+id/camera_image"android:layout_width="match_parent"android:layout_height="match_parent"android:contentDescription="@string/app_name" /><Buttonandroid:id="@+id/button1"style="?android:attr/buttonStyleSmall"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_alignParentTop="true" /></RelativeLayout>

Solution 3:

Just add a callback for starting preview on your camera instance. The thing is that after starting preview on camera instance, it needs some time to be able take a picture. Try this:

       camera.startPreview();
        camera.setOneShotPreviewCallback(newCamera.PreviewCallback() {
            @OverridepublicvoidonPreviewFrame(byte[] data, Camera camera) {
                camera.takePicture(null, null, newCamera.PictureCallback() {
                    @OverridepublicvoidonPictureTaken(byte[] data, Camera camera) {
               // do something you want with your picture and stop preview
                        camera.stopPreview();
                    }
                });

Post a Comment for "Camera.takepicture() Is Crashing My App"