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