camera.takePicture() is crashing my app

前端 未结 3 1636
甜味超标
甜味超标 2020-12-21 11:31

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 onCrea         


        
3条回答
  •  甜味超标
    2020-12-21 11:43

    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 :

    public class Cam_View extends Activity implements SurfaceHolder.Callback{
    
    protected static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
    private SurfaceView SurView;
    private SurfaceHolder camHolder;
    private boolean previewRunning;
    final Context context = this;
    public static Camera camera = null;
    private RelativeLayout CamView;
    private Bitmap inputBMP=null,bmp,bmp1;
    private ImageView mImage;
    
    
    
    
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(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 PREVIEW
    
    
    
        Button btn = (Button) findViewById(R.id.button1); //THE BUTTON FOR TAKING PICTURE
    
    
    
        btn.setOnClickListener(new OnClickListener()     //THE BUTTON CODE
        {
            public void onClick(View v)
            {
                      camera.takePicture(null, null, mPicture);//TAKING THE PICTURE
                                                             //THE mPicture IS CALLED 
                                                             //WHICH IS THE LAST METHOD(SEE BELOW)
                }
    
            });
    
        }
    
    
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,//NEEDED FOR THE PREVIEW
        int height) {
    if(previewRunning){
        camera.stopPreview();
    }
    Camera.Parameters camParams = camera.getParameters();
    Camera.Size size = 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();
    }
    }
    
    public void surfaceCreated(SurfaceHolder holder) {                  //NEEDED FOR THE PREVIEW
    try{
        camera=Camera.open();
    }catch(Exception e){
        e.printStackTrace();
        Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
        finish();
    }
    }
    
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {             //NEEDED FOR THE PREVIEW
    camera.stopPreview();
    camera.release();
    camera=null;
    }
    
    
    
    public void TakeScreenshot(){    //THIS METHOD TAKES A SCREENSHOT AND SAVES IT AS .jpg
    
    Random num = new Random();
    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);
    Bitmap bmp = Bitmap.createBitmap(CamView.getDrawingCache());
    CamView.setDrawingCacheEnabled(false); // clear drawing cache
                    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
                    bmp.compress(CompressFormat.JPEG, 100, bos); 
                    byte[] bitmapdata = bos.toByteArray();
                    ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
    
                    String picId=String.valueOf(nu);
                    String myfile="Ghost"+picId+".jpeg";
    
                    File dir_image = new  File(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 {
                        File tmpFile = new File(dir_image,myfile); 
                        FileOutputStream fos = new FileOutputStream(tmpFile);
    
                         byte[] buf = new byte[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();
                    }
    
    
    }
    
    private PictureCallback mPicture = new PictureCallback() {   //THIS METHOD AND THE METHOD BELOW
                                 //CONVERT THE CAPTURED IMAGE IN A JPG FILE AND SAVE IT
    
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
    
        File dir_image2 = new  File(Environment.getExternalStorageDirectory()+
                File.separator+"Ultimate Entity Detector");
        dir_image2.mkdirs();  //AGAIN CHOOSING FOLDER FOR THE PICTURE(WHICH IS LIKE A SURFACEVIEW 
                                //SCREENSHOT)
    
    
    
        File tmpFile = new File(dir_image2,"TempGhost.jpg"); //MAKING A FILE IN THE PATH                 
                        //dir_image2(SEE RIGHT ABOVE) AND NAMING IT "TempGhost.jpg" OR ANYTHING ELSE
        try {//SAVING
            FileOutputStream fos = new FileOutputStream(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();
        }
    
        String path = (Environment.getExternalStorageDirectory()+  
                File.separator+"Ultimate EntityDetector"+
                                            File.separator+"TempGhost.jpg");//<---
    
        BitmapFactory.Options options = new BitmapFactory.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 :

    
    
    
    
    
    
    
    
    
    

提交回复
热议问题