Android Textureview Full Screen Preview With Correct Aspect Ratio
Solution 1:
I was able to fix the issue by switching setMeasuredDimension();
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(height * mRatioWidth / mRatioHeight, height);
} else {
setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
}
}
Solution 2:
I let you below the code that we used to measure a preview which supports 4:3, 16:9 and 1:1 preview sizes. The height is scaled because the app is block in portrait, it does not rotate to landscape.
Hope it will help you or someone else with the same problem!
protectedvoidonMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
intwidth= MeasureSpec.getSize(widthMeasureSpec);
intheight= MeasureSpec.getSize(heightMeasureSpec);
Log.d(TAG, "[onMeasure] Before transforming: " + width + "x" + height);
introtation= ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation();
booleanisInHorizontal= Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation;
int newWidth;
int newHeight;
Log.d(TAG, "[onMeasure] Get measured dimensions: " + getMeasuredWidth() + "x" + getMeasuredHeight());
if (isInHorizontal) {
newHeight = getMeasuredHeight();
if (mAspectRatioOneOne) newWidth = getMeasuredHeight();
elsenewWidth= (int) (newHeight * mAspectRatio);
} else {
newWidth = getMeasuredWidth();
if (mAspectRatioOneOne) newHeight = getMeasuredWidth();
elsenewHeight= (int) (newWidth * mAspectRatio);
}
setMeasuredDimension(newWidth, newHeight);
Log.d(TAG, "[onMeasure] After transforming: " + getMeasuredWidth() + "x" + getMeasuredHeight());
}
Solution 3:
I had similar problem using Camera2 implementation. I used AutoFitTextureView implementation of TextureView as preview from camera, and want to adjust to correct ratio. My problem income from different implementations of methods and propagate to onSurfaceTextureSizeChanged. [1]com.google.android.cameraview.CameraView#onMeasure(..) -> [2]com.google.android.cameraview.AutoFitTextureView#onMeasure(..) -> [3]onSurfaceTextureSizeChanged(..)
Problem where in different if [1] than in [2]. I replaced in [1]:
if (height < width * ratio.getY() / ratio.getX()) {
to
if (!(height < width * ratio.getY() / ratio.getX())) {
because [2] had if based on width not height
if (width < height * mRatioWidth / mRatioHeight) {
Verify if methods onMeasure(..) are implemented correctly.
Or you could do like Edmund Rojas - above
Solution 4:
If you want full-screen, undistorted preview, then you have to select a preview resolution for the camera that matches the aspect ratio of your screen.
However, if your screen size isn't a standard size (16:9 or 4:3, basically), especially once you subtract off the soft buttons and the notification bar (assuming you're not completely full screen), then the only option for having the preview fill the screen is to cut some of it off.
You should be able to modify the TextureView's transform matrix to remove the distortion, by looking at the view's width and height and the selected preview width and height, but this will necessarily cut some of it off.
Solution 5:
AutoFitTextureView in layout should use wrap_content
<AutoFitTextureView
android:id="@+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
/**
* A [TextureView] that can be adjusted to a specified aspect ratio.
*/classAutoFitTextureView : TextureView {constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : super(context, attrs, defStyle)
privatevar ratioWidth = 0privatevar ratioHeight = 0/**
* 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
*/funsetAspectRatio(width: Int, height: Int) {
require(!(width < 0 || height < 0)) { "Size cannot be negative." }
ratioWidth = width
ratioHeight = height
requestLayout()
}
overridefunonMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
if (ratioWidth == 0 || ratioHeight == 0) {
setMeasuredDimension(width, height)
} else {
if (width < height * ratioWidth / ratioHeight) {
setMeasuredDimension(width, width * ratioHeight / ratioWidth)
} else {
setMeasuredDimension(height * ratioWidth / ratioHeight, height)
}
}
}
}
Post a Comment for "Android Textureview Full Screen Preview With Correct Aspect Ratio"