2013-08-17 40 views
2

我有一個應用程序,應該使用camera.takePicture拍照。我使用的代碼如下:camera.takePicture()崩潰我的應用程序

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弗羅澤的形象,但隨後的應用程序崩潰。這是爲什麼發生?當我使用模擬攝像頭在仿真器上運行它時,它在工作但在設備上崩潰。

+0

發佈logcat –

+0

但avd不會崩潰。只讀設備。 – mremremre1

回答

0

我終於解決了這個問題。下面我給想要知道如何截取佈局截圖,無意識地拍攝來自照相機的圖片,截取(排序)SurfaceView內容並將截屏保存在文件夾中的任何人的代碼:

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方法。

如果你想截取一個surfaceView的截圖並且不能直接從surfaceview中使用mPicture,請將捕獲的圖片設置爲背景,然後調用TakeScreenshot截取你的截圖(如上所示)

如果你想用照相機拍照而不用調用另一個照相機應用程序,並且意圖使用帶有mPicture的takePicture和上面代碼中的surfaceView東西。

以前的代碼如果按照「原樣」使用的話,就是對佈局內容(按鈕,圖像瀏覽等)進行截圖並設置爲從相機背景的圖像。

下面我還爲以前的代碼的基本佈局的xml:

<?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> 
+0

這給了我java.lang.NullPointerException –

0

使用這個簡單的代碼來捕獲使用設備攝像頭

IMP注:這些permision添加到mainfest文件

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

在MainActivity

public class MainActivity extends Activity { 

private static final int CAMERA_PIC_REQUEST = 1111;//Constant ID for ActivityResult 
private ImageView mImage; // To display the thumbnail 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

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

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

} 

@Override 
protected void onActivityResult(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 ImageView 
     if (data.getExtras() == null) 
      return; 
     Bitmap thumb = (Bitmap) data.getExtras().get("data"); 
     mImage.setImageBitmap(thumb); 

     // Compress the Bitmap image into JPEG to save it on the device 
     ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
     thumb.compress(Bitmap.CompressFormat.JPEG, 100, bytes);// 100 is the scale..for less quality decrease the number         

     // Save the image on the root SDCard 
     File file = new File(Environment.getExternalStorageDirectory() 
       + File.separator + "imageName.png"); 

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

    } 

} 

} 

把這個在你的佈局MainActivity .XML:

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

我尋找的是一種拍照的方式,並保存它,而不使用手機相機應用程序的意圖。 – mremremre1

+0

除了您的代碼將圖片保存爲縮略圖的質量 – mremremre1

+1

我的代碼將圖片保存在設備上,並將其顯示在佈局中的縮略圖中......您也沒有在您的問題中明確提及意圖問題。我希望這可以幫助 –

0

只需添加一個回調在您的相機實例開始預覽。事情是,在相機實例上開始預覽後,需要一些時間才能拍攝照片。試試這個:

 camera.startPreview(); 
     camera.setOneShotPreviewCallback(new Camera.PreviewCallback() { 
      @Override 
      public void onPreviewFrame(byte[] data, Camera camera) { 
       camera.takePicture(null, null, new Camera.PictureCallback() { 
        @Override 
        public void onPictureTaken(byte[] data, Camera camera) { 
       // do something you want with your picture and stop preview 
         camera.stopPreview(); 
        } 
       });