Android:保存时捕获的图像为零字节

时间:2014-04-05 23:29:54

标签: buffer android-camera

我对Android非常陌生,我正在尝试做一些简单的事情:使用相机API,我想要捕获图像并将其保存到目录中。

我认为我的主要问题是picturecallback()类。使用此代码,我可以将jpeg图像保存到SD卡上的已知目录中。我可以看到它在正确的位置;但是,文件大小为0字节,无法打开。

这是我的代码:

    PictureCallback myPictureCallback_JPG = new PictureCallback(){

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

   if (arg0 == null){
       Toast.makeText(AndroidCamera.this,
                  "Image not saved.  ",
                  Toast.LENGTH_LONG).show();
       return;
       //Why is it returning NULL the first time and a 0-byte thing next...
   }


   File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
   if (pictureFile == null){
       System.out.println("Error creating media file, check storage permissions: ");
       return;
   }

//    
   Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());

   try {

       FileOutputStream fos = new FileOutputStream(pictureFile);
       fos.write(arg0);
       fos.close();

    Toast.makeText(AndroidCamera.this,
      "Image saved: " + uriTarget.toString(),
      Toast.LENGTH_LONG).show();

   } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

   camera.startPreview();
  }};

当通过调试器时,字节数组arg0似乎包含了从-255到255的大量随机数。我不确定为什么任何图像值都会产生负数而不是它们实际上没有被正确捕获首先(捕获发生在oncreate)。

这是主要课程:

package com.example.androidcamera;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

//import com.example.androidcamera.R;

import android.app.Activity;
import android.content.ContentValues;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class AndroidCamera extends Activity implements SurfaceHolder.Callback{

 Camera camera;
 SurfaceView surfaceView;
 SurfaceHolder surfaceHolder;
 boolean previewing = false;
 LayoutInflater controlInflater = null;

 Button buttonTakePicture;

 final int RESULT_SAVEIMAGE = 0;
 public static final int MEDIA_TYPE_IMAGE = 1;
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

       getWindow().setFormat(PixelFormat.UNKNOWN);
       surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
       surfaceHolder = surfaceView.getHolder();
       surfaceHolder.addCallback(this);
       surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

       controlInflater = LayoutInflater.from(getBaseContext());
       View viewControl = controlInflater.inflate(R.layout.control, null);
       LayoutParams layoutParamsControl
        = new LayoutParams(LayoutParams.FILL_PARENT,
        LayoutParams.FILL_PARENT);
       this.addContentView(viewControl, layoutParamsControl);

       buttonTakePicture = (Button)findViewById(R.id.takepicture);
       buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
           @Override
           public void onClick(View arg0) {
            // TODO Auto-generated method stub
            //camera.takePicture(myShutterCallback,
              //myPictureCallback_JPG, myPictureCallback_JPG);
               camera.takePicture(null, null, myPictureCallback_JPG);
           }
       });

       LinearLayout layoutBackground = (LinearLayout)findViewById(R.id.background);
       layoutBackground.setOnClickListener(new LinearLayout.OnClickListener(){

   @Override
   public void onClick(View arg0) {
    // TODO Auto-generated method stub

    buttonTakePicture.setEnabled(false);
    camera.autoFocus(myAutoFocusCallback);
    //camera.
   }});
   }

   AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){

  @Override
  public void onAutoFocus(boolean arg0, Camera arg1) {
   // TODO Auto-generated method stub
   buttonTakePicture.setEnabled(true);
  }};

   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

   if (arg0 == null){
       Toast.makeText(AndroidCamera.this,
                  "Image not saved.  ",
                  Toast.LENGTH_LONG).show();
       return;
       //Why is it returning NULL the first time and a 0-byte thing next...
   }


   File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
   if (pictureFile == null){
       System.out.println("Error creating media file, check storage permissions: ");
       return;
   }

//    
   Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());

   try {

       FileOutputStream fos = new FileOutputStream(pictureFile);
       fos.write(arg0);
       fos.close();

    Toast.makeText(AndroidCamera.this,
      "Image saved: " + uriTarget.toString(),
      Toast.LENGTH_LONG).show();

   } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

   camera.startPreview();
  }};

 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
   int height) {
  // TODO Auto-generated method stub
  if(previewing){
   camera.stopPreview();
   previewing = false;
  }

  if (camera != null){
   try {
    camera.setPreviewDisplay(surfaceHolder);
    camera.startPreview();
    previewing = true;
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }

 @Override
 public void surfaceCreated(SurfaceHolder holder) {
  // TODO Auto-generated method stub
  camera = Camera.open();
 }

 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
  // TODO Auto-generated method stub
  camera.stopPreview();
  camera.release();
  camera = null;
  previewing = false;
 }

 /** Create a File for saving an image or video */
 private static File getOutputMediaFile(int type){
     // To be safe, you should check that the SDCard is mounted
     // using Environment.getExternalStorageState() before doing this.

     File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
               Environment.DIRECTORY_PICTURES), "MyCameraApp");
     // This location works best if you want the created images to be shared
     // between applications and persist after your app has been uninstalled.

     // Create the storage directory if it does not exist
     if (! mediaStorageDir.exists()){
         if (! mediaStorageDir.mkdirs()){
             Log.d("MyCameraApp", "failed to create directory");
             return null;
         }
     }

     // Create a media file name
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
     File mediaFile;
     if (type == MEDIA_TYPE_IMAGE){
         mediaFile = new File(mediaStorageDir.getPath() + File.separator +
         "IMG_"+ timeStamp + ".jpg");
     } else {
         return null;
     }

     return mediaFile;
 }

 @Override
 protected void onPause() {
     super.onPause();
     releaseCamera();              // release the camera immediately on pause event
 }

 private void releaseCamera(){
     if (camera != null){
         camera.release();        // release the camera for other applications
         camera = null;
     }
 }

}

我的AndroidManifest文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.androidcamera"
     android:versionCode="1"
     android:versionName="1.0">
   <application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
       <activity android:name="AndroidCamera"
                 android:label="@string/app_name">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>

   </application>
   <uses-sdk android:minSdkVersion="8" />
   <uses-permission android:name="android.permission.CAMERA"></uses-permission>
   <uses-feature android:name="android.hardware.camera" />
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   <uses-feature android:name="android.hardware.camera.autofocus" />
</manifest>

最后我的主要xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/background"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:gravity="bottom"
   >
<Button
 android:id="@+id/takepicture" 
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text=" * Take Picture "
 android:layout_gravity="right"
 android:layout_margin="10dp"
 />
</LinearLayout>

非常感谢提前。

0 个答案:

没有答案