简体   繁体   中英

Camera 2 Preview is stretched

I am currently making an android app using Camera2 API. I am facing a problem with AutoFitTextureView the image is showing stretched. My code for the AutoFitTextureView is as below

public class AutoFitTextureView extends TextureView {
private int mRatioWidth = 0;
private int mRatioHeight = 0;
private boolean mWithMargin = false;
public AutoFitTextureView(Context context) {
    this(context, null);
}
public AutoFitTextureView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}
public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

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);
        }
    }
}

XML Code-

Streched Image:

在此处输入图片说明

The XML code which I am using is as below the preview is coming stretched-

 <com.qopius.AutoFitTextureViewNew
        android:id="@+id/texture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         />

Try this code

@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) {
            if (width > height * mRatioWidth / mRatioHeight) {
                setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
            } else {
                setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
}
}

Try this one

@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);
        }
    }
}

You need to place the AutoFitTextureView in a parent View/container that allows it to adjust its sizing. If the parent View won't allow this, it will resize the textureview no matter what you do in its onMeasure.

For example, the Camera2Basic sample places the AutoFitTextureView in a RelativeLayout:

https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/res/layout/fragment_camera2_basic.xml

1.) Your portrait dividend and divisor are falsely reversed:

setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);

2.) The AutoFitTextureView sample's logic to distinguish the texture's orientations in onMeasure(..) is misleading:

if (width > height * mRatioWidth / mRatioHeight)

While it works well around 4:3 (emulators, S2, S4), it fails at larger aspect ratios (Essential PH-1). Adding the texture orientation to the setAspectRatio(..) method provides the needed information.

Note: The sample below ignores orientations 180° and 270°.

import android.util.AttributeSet;
class AutoFitTextureView extends TextureView {
    private int mRatioWidth = 0;
    private int mRatioHeight = 0;
    private int mTextureOrientation = 0;

    public AutoFitTextureView(Context context) {
        this(context, null);
    }
    public AutoFitTextureView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    public void setAspectRatio(int width, int height, int textureOrientation) {
        if ( width < 0 || height < 0 ) {
            throw new IllegalArgumentException("Size cannot be negative.");
        }
        mRatioWidth = width;
        mRatioHeight = height;
        mTextureOrientation = textureOrientation;
        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 ( mTextureOrientation == 0 ) { // 0 == portrait, 1 == landscape
                setMeasuredDimension(width, width * mRatioWidth/mRatioHeight);
            } else {
                setMeasuredDimension(height * mRatioWidth/mRatioHeight, height);
            }
        }
    }
}

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