4

I'd like to know how I can put a silhouette on top of a camera preview. So far i've got the following example working, which just previews the Camera.

http://developer.android.com/reference/android/view/TextureView.html

I'm trying to have a Camera preview, where I got a silhouette shown so the person using the app gets an idea of where the picture should be taken, and then a button that when clicked, takes the picture, without the silhouette of course in the picture.

How can this be done? I can't seem to find any examples of how to put an overlay on top of a texture view.

Mikkel Larsen
  • 876
  • 2
  • 14
  • 26
  • 2
    A `TextureView` behaves just like a regular `View`, so you'd do it just like you'd put any `View` over another `View`. – Mike M. Feb 04 '16 at 09:04
  • @MikeM. Let's say I don't know how to do that neither :D – Mikkel Larsen Feb 04 '16 at 09:43
  • There are plenty of examples already here on-site, but a quick description of a possible option: create a layout XML file with a `FrameLayout` as the root `View`. List the `TextureView` as the first child of the `FrameLayout`, with its `layout_width` and `layout_height` set to `match_parent`. List an `ImageView` as the second child with the same dimensions, make its `background` transparent - `#00000000` - and set its `src` to your silhouette image, which should also have a transparent background. Then load your layout file in the `setContentView()` call instead of just the `TextureView`. – Mike M. Feb 04 '16 at 09:51
  • @MikeM. I'll give it a go. Thank you. – Mikkel Larsen Feb 04 '16 at 09:59
  • @MikeM. I really can't seem to get any example to work :/ – Mikkel Larsen Feb 04 '16 at 11:41
  • Gimme a minute. I'll post a quick example. – Mike M. Feb 04 '16 at 11:53
  • @MikeM. That'll be perfect! – Mikkel Larsen Feb 04 '16 at 12:05

1 Answers1

10

Using the example in the TextureView docs you've linked, we simply create a layout XML file to hold our TextureView and overlay ImageView in a FrameLayout. We then call the Activity's setContentView() method with this layout's Resource ID, instead of the dynamically-created TextureView in the example.

The layout file, main.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextureView android:id="@+id/texture_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView android:id="@+id/image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#00000000"
        android:src="@drawable/ic_launcher" />

</FrameLayout>

And the sample Activity:

public class LiveCameraActivity extends Activity
    implements TextureView.SurfaceTextureListener {

    private Camera mCamera;
    private TextureView mTextureView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mTextureView = (TextureView) findViewById(R.id.texture_view);
        mTextureView.setSurfaceTextureListener(this);
    }

    // The TextureView.SurfaceTextureListener methods
    // are the same as shown in the example.

    ...
}

The overlay ImageView in the layout uses the default launcher icon as its source image, as it has transparency, at least on my IDE. You would later replace this image with your silhouette. The ImageView, being listed after the TextureView, will appear on top of it, because Views are drawn with respect to their z-order in the same order they're listed in the layout, with the first View listed being on the bottom; i.e., the farthest away from you on the z-axis.

In the Activity, we're just loading the layout as the content View, and getting a reference to the TextureView created there. Everything else is the same.

Mike M.
  • 38,532
  • 8
  • 99
  • 95
  • 1
    Nothing short of amazing! I've tried for hours to make this work, and I feel like I've done exactly what you just wrote, several times. But this worked! Thank you so much man! Have a wonderful day! – Mikkel Larsen Feb 04 '16 at 12:42
  • The camera now fills the entire screen. Would you know how to make it smaller? I tried adding in stuff like: Camera.Parameters parameters = camera.GetParameters(); parameters.SetPictureSize(width, height); camera.SetParameters(parameters); But that doesn't seem to solve it. It remains same size all the time. – Mikkel Larsen Feb 04 '16 at 14:16
  • Yeah, you would change the size of the `TextureView`; actually the parent `FrameLayout`. You can treat my sample layout as kind of a single `View`, and put it inside whatever other layout you want, like you would when you add a `Button` or an `EditText` to an `Activity`'s layout. Does that make sense? – Mike M. Feb 04 '16 at 14:37
  • Okay. Sorry for asking you yet again, but I'm not very familiar with Android. Let's say I'd like a black frame, within that I want a TextureView(The image the camera is previewing), but It has to be slightly smaller than the frame, so I can see it around the Textureview. And in the bottom of the black frame, I'd like a button to Capture the Image. How would that look like(If you got the time for that :) ) – Mikkel Larsen Feb 04 '16 at 14:57
  • Yeah, [here ya go](https://drive.google.com/file/d/0B0yCxiylEdYkVGc1ZFRWOHlXMjQ/view?usp=docslist_api). I still had my editor open with that layout, so it was a quick adjustment. Lemme know if you have trouble accessing that. I don't use Drive very often. – Mike M. Feb 04 '16 at 15:24
  • Brilliant, I'll check this tomorrow! :D – Mikkel Larsen Feb 04 '16 at 15:58