2011-06-13 20 views
7

Estoy usando SurfaceView con SurfaceHolder para comenzar con una vista previa de la cámara en la aplicación de prueba.Imagen de la leva en el soporte de la superficie, dibujo: Excepción por el tipo de superficie

public class TextLocatorActivity extends Activity { 

    private Preview pvw; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     pvw = new Preview(this); 
     setContentView(pvw);   
    } 

Quiero usar la cámara previa (viene con las muestras de SDK para SDK versión 7). Un clic en la interfaz de usuario toma una foto. Aquí está la clase Preview:

public class Preview extends SurfaceView implements OnClickListener, SurfaceHolder.Callback { 

SurfaceHolder holder; 
Camera cam; 

final static String TAG = "TextLocator:Preview"; 

Preview(Context context) { 
    super(context); 

    holder = getHolder(); 
    holder.addCallback(this); 
    this.setOnClickListener(this); 
    // seems to be required (although the docs state, this enum is deprecated, as the type will be chosen automatically... 
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    cam = Camera.open(); 
    try { 
     Camera.Parameters params = cam.getParameters(); 
     params.set("orientation", "landscape"); 
     Camera.Size bestSize = getBestPreviewSize(480, 320); 
     params.setPreviewSize(bestSize.width, bestSize.height); 
     cam.setParameters(params); 
     // where to draw: 
     cam.setPreviewDisplay(holder); 
    } catch (IOException exception) { 
     cam.release(); 
     cam = null; 
     // TODO: add more exception handling logic here 
    } 
} 

private Camera.Size getBestPreviewSize(int width, int height) 
{ 
    // checks for supported sizes close to the demanded values - implemented. 
} 


public void surfaceDestroyed(SurfaceHolder holder) { 
    cam.stopPreview(); 
    cam.release(); 
    cam = null; 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    Camera.Parameters parameters = cam.getParameters(); 
    parameters.setPreviewSize(w, h); 

    cam.setParameters(parameters); 
    cam.startPreview(); 
} 

Camera.PictureCallback picCallback = new Camera.PictureCallback() { 

    public void onPictureTaken(byte[] bytes, Camera arg1) { 
     synchronized(holder) { 
       Canvas c = null;  

       try { 
        c = holder.lockCanvas();     

        Paint paint = new Paint(); 
        paint.setAntiAlias(false); 
        paint.setARGB(200, 120, 180, 0); 

        c.drawLine(10, 10, c.getWidth() - 10, c.getHeight() - 10, paint); 
       } 
       catch (Exception e) { 
        Log.d(TAG, "Exception: " + e.getMessage()); 
        // IllegalArguementException Surface Type is SURFACE_TYPE_PUSH_BUFFERS 
       } 
       finally {  
        holder.unlockCanvasAndPost(c); 
       } 
      } 
    } 
}; 

public void onClick(View v) 
{ 
    cam.takePicture(null, null, picCallback);  
} 

}

Siguiente Estoy tratando de hacer un poco de pintura adicional a la correspondiente Canvas del SurfaceHolder. Por lo tanto, estoy llamando al canvas = holder.lockCanvas(). Esto dará lugar a un IllegalArgumentException con el mensaje:

Surface type is SURFACE_TYPE_PUSH_BUFFERS 

Ahora, docs estado que esos tipos de superficie están en desuso, el conjunto de valores serán ignorados. Sin embargo, la vista previa de la cámara solo funciona, si configuro el tipo a este valor específico.

¿Cómo puedo obtener el dibujo en el Canvas del SurfaceView en el que se muestra la imagen? ¿O debería colocarse en una capa/vista diferente?

+1

En cuanto a mi pregunta de cierre, hay un enfoque para usar una vista adicional y aprovechar eso. Está utilizando 'RealtiveLayout' o' FrameLayout' para preservar el orden z de 'SurfaceView' y esa superposición: http://stackoverflow.com/questions/2933882/how-to-draw-an-overlay-on-a- surfaceview-used-by-camera-on-android – rdoubleui

+0

FYI: La solución en el enlace de arriba fue útil y terminé usando este enfoque al usar una vista adicional encima de la vista previa de la cámara. – rdoubleui

Respuesta

5

No puede mostrar la vista previa de la cámara y dibujar con un lienzo. Tienes que hacer uno o el otro.

+0

Si bien eso seguramente es cierto, ¿podría elaborar o dar alguna pista sobre dónde encontrar documentación sobre este tema? Porque creo que Android simplemente cargaría el búfer de la vista previa en la vista y debería poder recurrir a él. – rdoubleui

+2

No hay mucho más que decir, cuando se usa SurfaceView, la superficie asociada se puede usar para un solo tipo de renderizado: video, GPU o software. Una vez que se eligió un tipo de representación, no se puede usar para otro tipo. Se trata del formato de los búferes en la memoria y dónde se almacena esa memoria. –

Cuestiones relacionadas