1

I'm really stuck on my work. I read a lot of questions&answers on stackoverflow but still I can't find the exact answer that would suit me. Please help me or even just point me in the right direction...

I'm trying to write an application that would let me choose an object on the screen while using the camera.

I'll try to explain it in a more simple way: I turn on the application, the camera live screen appears as if I was recording something. I use my finger and select 3 specific points on the screen (these would be small color paper squares I've prepared earlier). My choice is saved to the phone. (I'll stop here because I think further explanation of what happens next is not important here).

I don't know how to create a program/code that would let me select those points on the screen. All I have now is a simple code that only turns on the camera and lets you record videos.

Please help.

  • You need to get the camera up and running and attach it to a surfaceview. You can then build another surfaceview above the first one. Using a custom UI higher in the z axis(you cant use a canvas of a surfaceview when its attached to the camera so you need a second one). The higher surfaceview can use/draw on a canvas object. This can also use touch events. The camera preview and the surfaceview will be different sizes so caluclate that. When you touch the screen use the touch event to get the coordinates and convert these to camera coordinates. Is this what you need? I can explain in full. – James Burnstone Nov 05 '13 at 15:52
  • Thank you James. Your answer gives me an idea how to start but still I don't quite understand it. I know how it is to help and explain everything to a rookie - because that's who I am in programming now, but I would love if you "can explain in full" as much as you may so I understand everything fully. I'd really appreciate it. – user2887005 Nov 05 '13 at 16:40

1 Answers1

1

You're code to start the video feed, I would assume, gets a Camera object, starts it and connects it to a SurfaceView maybe a SurfaceTexture. The frames from the Camera are directly displayed to the SurfaceView if you have set:

myHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
myCamera.setPreviewDisplay(myHolder);

This is a fast and easy way to display the camera frames, but it means you cannot control how the frames are displayed. For instance, if you wanted to process the frames and then display them yourself, you would need to subscribe to the onPreviewCallback() which gives you a copy of each frame. If you then omitted the above two surfaceview lines, the frames would not be automatically displayed and you could draw them yourself, however this would be alot slower. https://stackoverflow.com/a/4367250/514531

You can draw on top of a surfaceview using a Canvas. A canvas has many methods for drawig shapes/rectangles/lines/circles/words etc. You use Paint objects to specfify color/width etc. Im sorry if this is wrong now but I have been using an older Android, but, if you do display via the surfaceview you cannot lock a canvas to the surfaceview. https://stackoverflow.com/a/12565208/514531 To get around this I found some code a while ago which creates an OverlayView class. In Android you can place views on top of each other in the Z direction. Using an empty transparent surfaceview that doesnt use myHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); myCamera.setPreviewDisplay(myHolder); you can lock a canavs to it and start drawing.

The OverlayView class is simply a class extending SurfaceView and is used as a custom display. To do this you need to declare it in your layout file for your first/camera activity, like this:

 <Your.package.OverlayView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/overView"
    />
     <SurfaceView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/surfaceView"/>

In this layout file R.id.surfaceView is your first surfaceview you use with the camera and set up like you probably already have. The R.id.overView is the custom surfaceview for drawing.

You can create it like any other view component:

OverLayView overView = (OverlayView)findViewById(R.id.overView);

This acts like a normal class as well so you can send some parameters to it as normal and call methods on it. For instance I have a method:

overView.setCamera(myCamera, cameraHeight, cameraWidth, getResources(), isFrontCamera);

Now you have a camera displaying to a surfaceview and a separate surfaceview you can draw to. So you now need a TouchEvent handler.

In the OverlayView class override the method onTouchEvent(MotionEvent e). The MotionEvent tells you what event occured, touch on/off. First check that it is a touch down(press on the screen) and then you can get the X and Y coordinates from the MotionEvent e.getX;

This could be combined with the canavs to draw where a touch as occurred.

On thing to note: The dimensions of the camera preview will probably be different to that of the surfaceview. You know the camera dimensions from the camera object and the surfaceview sizes are from the surfaceView onchange method. So you need to calculate a ratio to convert the two, something like: (viewWidth/touch)*camerawidth.

Once you have the coordinates you could use crop the camera frame where you want.

Community
  • 1
  • 1
James Burnstone
  • 594
  • 1
  • 7
  • 17