Cómo dibujar una superposición en un SurfaceView utilizado por la cámara en Android?
Tengo un programa simple que dibuja la vista previa del Camera
en un SurfaceView
. Lo que estoy tratando de hacer es usar el método onPreviewFrame
, que se invoca cada vez que se dibuja un nuevo marco en el SurfaceView
, para ejecutar el método invalidate
que se supone que invoca el método onDraw
. De hecho, se está invocando el método onDraw
, pero no se está imprimiendo nada (supongo que la vista previa de la cámara está sobrescribiendo el texto que estoy tratando de dibujar).
Esta es una versión simplificada de la subclase SurfaceView
I tienen:
public class Superficie extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
public Camera camera;
Superficie(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(final SurfaceHolder holder) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
invalidar();
}
});
} catch (IOException e) {}
}
public void invalidar(){
invalidate();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
// nothing gets drawn :(
Paint p = new Paint(Color.RED);
canvas.drawText("PREVIEW", canvas.getWidth() / 2,
canvas.getHeight() / 2, p);
}
}
3 answers
SurfaceView
probablemente no funciona como un regular View
en este sentido.
En su lugar, haga lo siguiente:
- Ponga su
SurfaceView
dentro de unaFrameLayout
oRelativeLayout
en su archivo XML de diseño, ya que ambos aquellos permiten apilar widgets en el eje Z - Mueve tu lógica de dibujo
en una clase personalizada
View
- Agregar una instancia de la vista personalizada
clase al archivo XML de diseño como
hijo del
FrameLayout
oRelativeLayout
, pero que aparezca después de laSurfaceView
Esto hará que su clase personalizada View
aparezca flotando por encima de SurfaceView
.
Vea aquí un proyecto de ejemplo que capas de paneles emergentes por encima de un SurfaceView
utilizado para la reproducción de vídeo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-02 05:15:27
Intenta llamar a setWillNotDraw(false)
desde surfaceCreated
:
public void surfaceCreated(SurfaceHolder holder) {
try {
setWillNotDraw(false);
mycam.setPreviewDisplay(holder);
mycam.startPreview();
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG,"Surface not created");
}
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(area, rectanglePaint);
Log.w(this.getClass().getName(), "On Draw Called");
}
Y llamando invalidate
desde onTouchEvent
:
public boolean onTouch(View v, MotionEvent event) {
invalidate();
return true;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-16 23:19:18
Creo que deberías llamar al método super.draw()
primero antes de hacer algo en el método draw de SurfaceView.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-20 09:12:01