2011-08-19 11 views
7

Estoy usando código de cámara para Android después de tomar la foto del byte [] El parámetro imageData es nulo, no sé por qué.datos de devolución de llamada de Android es nulo

package com.pictures; 

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 


import android.app.Activity; 
import android.content.Context; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.PixelFormat; 
import android.graphics.Bitmap.CompressFormat; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.Window; 
import android.view.WindowManager; 
import android.view.View.OnClickListener; 
import android.view.View.OnTouchListener; 

public class CamaraView extends Activity implements SurfaceHolder.Callback, 
     OnClickListener { 
    static final int FOTO_MODE = 0; 
    private static final String TAG = "CameraTest"; 
    Camera mCamera; 
    boolean mPreviewRunning = false; 
    private Context mContext = this; 

    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 

     Log.e(TAG, "onCreate"); 

     Bundle extras = getIntent().getExtras(); 

     getWindow().setFormat(PixelFormat.TRANSLUCENT); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     setContentView(R.layout.main); 
     mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera); 
     mSurfaceView.setOnClickListener(this); 
     mSurfaceHolder = mSurfaceView.getHolder(); 
     mSurfaceHolder.addCallback(this); 
     mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 
    } 

    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { 
     public void onPictureTaken(byte[] imageData, Camera c) { 

      if (imageData != null) { 

       Intent mIntent = new Intent(); 

       StoreByteImage(mContext, imageData, 50, 
         "ImageName"); 
       mCamera.startPreview(); 

       setResult(FOTO_MODE, mIntent); 
       finish(); 

      } 
     } 
    }; 

    protected void onResume() { 
     Log.e(TAG, "onResume"); 
     super.onResume(); 
    } 

    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
    } 

    protected void onStop() { 
     Log.e(TAG, "onStop"); 
     super.onStop(); 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     Log.e(TAG, "surfaceCreated"); 
     mCamera = Camera.open(); 

    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     Log.e(TAG, "surfaceChanged"); 


     // XXX stopPreview() will crash if preview is not running 
     if (mPreviewRunning) { 
      mCamera.stopPreview(); 
     } 

     Camera.Parameters p = mCamera.getParameters(); 
     p.setPreviewSize(w, h); 
     mCamera.setParameters(p); 

     try { 
      mCamera.setPreviewDisplay(holder); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      System.out.println("Caught exception in surface chagned"); 
      e.printStackTrace(); 
     } 
     mCamera.startPreview(); 
     mPreviewRunning = true; 

    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     Log.e(TAG, "surfaceDestroyed"); 
     mCamera.stopPreview(); 
     mPreviewRunning = false; 
     mCamera.release(); 
    } 

    private SurfaceView mSurfaceView; 
    private SurfaceHolder mSurfaceHolder; 

    public void onClick(View arg0) { 

     mCamera.takePicture(null, mPictureCallback, mPictureCallback); 

    } 

    public static boolean StoreByteImage(Context mContext, byte[] imageData, 
      int quality, String expName) { 

     File sdImageMainDirectory = new File("/sdcard"); 
     FileOutputStream fileOutputStream = null; 
     String nameFile; 
     try { 

      BitmapFactory.Options options=new BitmapFactory.Options(); 
      options.inSampleSize = 5; 

      Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0, 
        imageData.length,options); 


      fileOutputStream = new FileOutputStream(
        sdImageMainDirectory.toString() +"/image.jpg"); 


      BufferedOutputStream bos = new BufferedOutputStream(
        fileOutputStream); 

      myImage.compress(CompressFormat.JPEG, quality, bos); 

      bos.flush(); 
      bos.close(); 

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

     return true; 
    } 

} 
+0

¿Qué es exactamente nulo? puntero a los datos que recibió en la devolución de llamada, el contenido del archivo en la tarjeta SD? –

+0

hi, public void onPictureTaken (byte [] data, cámara de cámara) en este parámetro de datos de línea es nulo ... – max

+0

Bueno, esto podría tener muchos motivos: la configuración de la cámara es de alguna manera complicada. Sería necesario ver cómo se configura la cámara y solicitar una devolución de llamada. –

Respuesta

9

Ok, veo el problema. Está reutilizando la devolución de llamada de imagen para las devoluciones de llamada en bruto y jpeg. Y desde javadoc puede leer:

Dispara una captura de imágenes asincrónica. El servicio de la cámara iniciará una serie de devoluciones de llamadas a la aplicación a medida que progresa la captura de la imagen . La devolución de llamada del obturador se produce después de capturar la imagen. Esto se puede utilizar para activar un sonido que permita al usuario saber que se ha capturado la imagen . La devolución de llamada sin formato se produce cuando los datos de imagen en bruto son disponibles (NOTA: los datos serán nulos si no hay memoria de devolución de llamada disponible o si el búfer de devolución de imagen sin procesar no es lo suficientemente grande como para contener la imagen sin procesar). La devolución de llamada posterior a la vista ocurre cuando está disponible una imagen de vista posterior a escala, completamente procesada (NOTA: no todo el hardware es compatible con esto). La devolución de llamada jpeg ocurre cuando la imagen comprimida está disponible. Si la aplicación no necesita una devolución de llamada en particular , se puede pasar un nulo en lugar de un método de devolución de llamada.

Así que si se llamó como devolución de llamada sin formato, los datos podrían ser nulos. Si no le gustan los datos brutos, solo use:

mCamera.takePicture(null, null, mPictureCallback); 
+0

@ Konstantin Pribluda muchas gracias y mucho que funcionó. – max

+1

¡no funciona en Motorola! – Toshe

+0

Bueno, en mi caso todo funciona bien en Samsung galaxy note y otros dispositivos de gama alta, incluso funciona muy bien en el emulador, pero en dispositivos como HTC Wildfire S y otros dispositivos de gama baja, algunos –

Cuestiones relacionadas