camera.takePicture()崩溃我的应用程序我的、应用程序、camera、takePicture

2023-09-05 03:15:26 作者:来自神经病院的你

我有一个应用程序,应该使用更多的camera.takePicture图片。在code我用的是以下内容:

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.setOnClickListener(new OnClickListener(){

    public void onClick(View v){
        camera.takePicture(myShutterCallback, 
                myPictureCallback_RAW, myPictureCallback_JPG);
    }
    });


 //inside the activity
 ShutterCallback myShutterCallback = new ShutterCallback(){

@Override
public void onShutter() {
    // TODO Auto-generated method stub

}};

PictureCallback myPictureCallback_RAW = new PictureCallback(){

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

}};

PictureCallback myPictureCallback_JPG = new PictureCallback(){

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

当我点击该按钮,快门声音响起,在surfaceView弗罗泽的形象,但随​​后的应用程序崩溃。这究竟是为什么?当我在模拟器上运行它与模拟摄像头的工作,但在设备上的崩溃。

When i click the button the shutter sound plays, the image on the surfaceView frozes but then the app crashes . Why is this happening ? When i run it on the emulator with an emulated camera its working but on a device is crashing.

推荐答案

我终于解决了这个。下面我给一些code谁想要知道如何利用布局截图,照片从相机无意图,一surfaceView内容的截图(某种程度上),并保存屏幕截图文件夹中:

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

}
};
 }

如果你想利用一个简单的截图(没有摄像头饲料需要),你可以单独使用TakeScreenshot方法。

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

如果你想利用一个surfaceView的截图与不可能从surfaceview直接使用mPic​​ture做,设置图片捕捉为的backgroung,然后调用TakeScreenshot把你的截图。(如上所示)

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)

如果你想使用相机拍摄的照片,而无需调用的其他相机应用,意图利用takePicture与mPicture和surfaceView东西从code以上。

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.

如果使用了previous code做原样采取的版面内容(按钮,imageviews等)的屏幕截图和设定的backgroung图像从相机。

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.

下面我还提供了一个基本的布局XML为previous code:

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"   
android:id="@+id/camview">

<SurfaceView
    android:id="@+id/sview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" />

<ImageView
    android:id="@+id/camera_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:contentDescription="@string/app_name" />



<Button
    android: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>