简体   繁体   中英

Android camera preview capture/resizing captured image to match preview

I am trying to create and application that requires me to take the previously captured image and place it over the current camera preview with about 0.5 alpha. This "overlay" image serves as a guide for capturing the next picture; the client will use the overlay to compare the current frame in the preview to the previously captured image. A simple way to approach this was to retrieve the last file that was captured and set that to a view. However, the captured image does not always match the camera previews resolution and aspect ratio, causing the overlay and preview to mismatch in representation of objects (the same object can vary in size between the preview and the captured image). I have tried:

  • Using Camera Preview callbacks to store the current frame data, this is inefficient and doesnt always work well (also has a slight translation, dimensions are accurate)
  • Using the aforementioned previous-file method and trying to scale down or scale up accordingly, match aspect ratio (maybe my math was wrong [I used the aspect ratio of the preview to calculate the area in the original image] and it is still possible to use this approach? If someone could way in on this it would be appreciated).
  • Researching ways to capture the contents of a surface view, to no avail.

Currently, two possible methods I would like insight on how I would approach would be:

  • Freeze the SurfaceView somehow (locking the canvas of some sort), set the opacity and use another SurfaceView to display the camera (maybe inefficient, clunky workaround?).
  • Capture the contents of the SurfaceView and store in a bitmap when the PictureCallback is called (preferred).

Ofcourse, any other suggestions would be greatly appreciated.

NOTE: There are similar questions and I've spent hours going through them but none of them correctly address my issue or give enough detail.

I got it to work using two TextureView components:

  • One is set to 0.5 alpha and lays on top of the other using a RelativeLayout.
  • Have the opaque TextureView register a SurfaceTextureListener
  • Start the camera triggered by onSurfaceTextureAvailable in said listener
  • Set the given SurfaceTexture as previewTexture
  • At button press, draw getBitmap() on the canvas of the transparent TextureView

Activity.java (implementing SurfaceTextureListener):

@Override
public void onClick(View view) {
{
    Canvas canvas = alphaCameraTextureView.lockCanvas();
    canvas.drawBitmap( cameraTextureView.getBitmap(), 0, 0, null );
    alphaCameraTextureView.unlockCanvasAndPost( canvas );
}

@Override
public void onSurfaceTextureAvailable( SurfaceTexture surfaceTexture, int width, int height )
{
    try
    {
        camera = Camera.open();
        camera.setDisplayOrientation( 90 );
        camera.setPreviewTexture( surfaceTexture );
        camera.startPreview();
    }
    catch (IOException e ) { e.printStackTrace(); }
}

@Override
public boolean onSurfaceTextureDestroyed( SurfaceTexture surfaceTexture )
{
    camera.stopPreview();
    camera.release();
    return false;
}

TextureViews in the layout.xml:

<TextureView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/cameraTextureView"
    android:layout_weight="0"/>

<TextureView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/alphaCameraTextureView"
    android:alpha="0.5"
    android:layout_weight="0" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM