views:

1303

answers:

1

I have a simple program that draws the preview of the Camera into a SurfaceView. What I'm trying to do is using the onPreviewFrame method, which is invoked each time a new frame is drawn into the SurfaceView, in order to execute the invalidate method which is supposed to invoke the onDraw method. In fact, the onDraw method is being invoked, but nothing there is being printed (I guess the camera preview is overwriting the text I'm trying to draw).

This is a simplify version of the SurfaceView subclass I have:

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);
 }
}
+1  A: 

SurfaceView probably does not work like a regular View in this regard.

Instead, do the following:

  1. Put your SurfaceView inside of a FrameLayout or RelativeLayout in your layout XML file, since both of those allow stacking of widgets on the Z-axis
  2. Move your drawing logic into a separate custom View class
  3. Add an instance of the custom View class to the layout XML file as a child of the FrameLayout or RelativeLayout, but have it appear after the SurfaceView

This will cause your custom View class to appear to float above the SurfaceView.

See here for a sample project that layers popup panels above a SurfaceView used for video playback.

CommonsWare
Thanks so much... that's a nice example and I'm sure that's all I need to do what I want :)
Cristian
@CommonsWare So will this answer that you supplied work in a situation where you are trying to overlay one surfaceview on top of another surfaceview? What do you mean by custom View class? The reason that I'm asking is because I'm facing a similar problem located here: http://stackoverflow.com/questions/3548666/overlay-images-onto-camera-preview-surfaceview
rohanbk
@rohanbk: You cannot overlay two `SurfaceView` widgets, as I understand it. "What do you mean by custom View class?" -- your own subclass of `android.view.View`, or your own subclass of an existing widget class.
CommonsWare
@CommonsWare So, in your honest opinion, would there be any way for me to modify the SurfaceViewOverlay example in the API demos (http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/SurfaceViewOverlay.html) so that I can draw bitmap images in a surfaceview on top of a camera surfaceview using the FrameLayout?
rohanbk
@rohanbk: You do not need a `SurfaceView` to draw bitmap images. For example, `ImageView` does not use a `SurfaceView`, AFAIK.
CommonsWare
@CommonsWare I'm building an Augmented Reality tool, so I need to update the positions of many images (the images are 50x50px png files) on the screen very rapidly. I tried using a View, but it wasn't fast enough. I used a SurfaceView to draw the images, and it worked, but I wasn't able to overlay it onto the camera (since according to you, surfaceview overlaying doesn't work). Will an ImageView be able to quickly render images on the phone screen? Also, thank you for all the help you've given. I really appreciate it.
rohanbk
@rohanbk: I have no idea how the AR apps do it -- sorry!
CommonsWare
@CommonsWare Thanks for all the other advice though. I've been grappling with a means to overlay a rapidly updating view on top of a live camera feed for a while now.
rohanbk