Camera2 with SurfaceView

I'm trying to get the new Camera2 to work with a simple SurfaceView, and I'm having some problems with real-time preview. On some devices, the image is stretched out of proportion, looking good at others.

I installed SurfaceView, which I programmatically adjust to fit the size of the preview stream size.

In the Nexus 5, it looks great, but one of them Samsung disconnects. In addition, Samsung devices have a black frame on the right side of the preview.

Is it impossible to work with SurfaceView or is it time to switch to TextureView?

+6
source share
3 answers

Yes, of course it is possible. Note that SurfaceView and its associated Surface are two different things, and each can / should be assigned a size.

Surface is the actual memory buffer that will hold the output of the camera, and thus its size determines the size of the actual image that you will receive from each frame. For each format available from the camera, there is a small set of possible (exact) sizes that you can make for this buffer.

SurfaceView is what this image displays when it is available, and can be basically any size in your layout. It will stretch its underlying linked image data to fit all of its layout sizes, but note that the size of this screen is different from the size of the data. Android will automatically resize image data to display. This is what probably causes your sprain.

For example, you can make an autofit based on a SurfaceView View, similar to camera2basic AutoFitTextureView, as follows (this is what I use):

 import android.content.Context; import android.util.AttributeSet; import android.view.SurfaceView; public class AutoFitSurfaceView extends SurfaceView { private int mRatioWidth = 0; private int mRatioHeight = 0; public AutoFitSurfaceView(Context context) { this(context, null); } public AutoFitSurfaceView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AutoFitSurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio * calculated from the parameters. Note that the actual sizes of parameters don't matter, that * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result. * * @param width Relative horizontal size * @param height Relative vertical size */ public void setAspectRatio(int width, int height) { if (width < 0 || height < 0) { throw new IllegalArgumentException("Size cannot be negative."); } mRatioWidth = width; mRatioHeight = height; requestLayout(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (0 == mRatioWidth || 0 == mRatioHeight) { setMeasuredDimension(width, height); } else { if (width < height * mRatioWidth / mRatioHeight) { setMeasuredDimension(width, width * mRatioHeight / mRatioWidth); } else { setMeasuredDimension(height * mRatioWidth / mRatioHeight, height); } } } } 
+1
source

The docs for createCaptureSession say

To draw a SurfaceView: as soon as you create a SurfaceView surface, set the surface size using setFixedSize (int, int) so that one of the sizes returned by getOutputSizes (SurfaceHolder.class)

+1
source

I have never worked with Camera2 (but very interesting in the new technology), and all I can offer is to follow the samples. And if you check it carefully, the sample uses a custom TextureView , you should try to copy it into your project:

http://developer.android.com/samples/Camera2Basic/src/com.example.android.camera2basic/AutoFitTextureView.html

 /** * A {@link TextureView} that can be adjusted to a specified aspect ratio. */ public class AutoFitTextureView extends TextureView { 

also given that the difference between SurfaceView and TextureView (theoretically) is that you can use it as a normal view in the layout, and the other β€œhits the whole” through the hierarchy of views and that Camera2 is only available in API21 + ... there should be no harm when switching to TextureView

0
source

All Articles