Following are the screenshots when using texture view in camera2 apis.In full screen the preview stretches,but it works when using lower resolution(second image). How to use this preview in full screen without stretching it.

- 20,807
- 14
- 73
- 124

- 3,855
- 2
- 30
- 42
-
did you manage to find the solution? @akash – Mohsin Oct 04 '17 at 07:45
-
did'nt find solution till now!! @user3819810 – Akash Bisariya Oct 09 '17 at 08:12
-
Is this some kind of limitation! what do u feel? – Mohsin Oct 09 '17 at 10:32
-
may be but i am not sure about. – Akash Bisariya Oct 09 '17 at 10:36
-
There are some apps which are opening preview in full screen but with some zoom. – Akash Bisariya Oct 09 '17 at 10:36
-
Tell me the name of app. link please – Mohsin Oct 10 '17 at 12:05
-
1https://play.google.com/store/apps/details?id=com.footej.camera – Akash Bisariya Oct 10 '17 at 12:40
-
Have you found any solution to this – FaisalAhmed Nov 02 '17 at 06:56
-
no @FaisalAhmed – Akash Bisariya Nov 03 '17 at 05:15
-
How can we in a best way solve this, if anyone did, please update on this issue. thanks. – Mohsin Nov 30 '17 at 08:22
-
any luck guys ? please share – Mohsin Dec 25 '17 at 17:08
-
What are the preview sizes used on the two screenshots? – Alex Cohn Mar 22 '18 at 15:59
-
share the code you use to show this preview – Nick Cardoso Mar 23 '18 at 12:29
-
Can you provide a [mcve] to reproduce and maybe fix the problem. DIdn't had the time to dig the v.2 API so it could be easier. – AxelH Mar 23 '18 at 12:29
4 Answers
Below answer assumes you are in portrait mode only.
Your question is
How to use the preview in full-screen without stretching it
Let's break it down to 2 things:
- You want the preview to fill the screen
- The preview cannot be distorted
First you need to know that this is logically impossible without crop, if your device's viewport has a different aspect ratio with any available resolution the camera provides.
So I would assume you accept cropping the preview.
Step 1: Get a list of available resolutions
StreamConfigurationMap map = mCameraCharacteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
throw new IllegalStateException("Failed to get configuration map: " + mCameraId);
}
Size[] sizes = map.getOutputSizes(SurfaceTexture.class);
Now you get a list of available resolutions (Sizes) of your device's camera.
Step 2: Find the best aspect ratio
The idea is to loop the sizes and see which one best fits. You probably need to write your own implementation of "best fits".
I am not going to provide any code here since what I have is quite different from your use case. But ideally, it should be something like this:
Size findBestSize (Size[] sizes) {
//Logic goes here
}
Step 3: Tell the Camera API that you want to use this size
//...
textureView.setBufferSize(bestSize.getWidth(), bestSize.getHeight());
Surface surface = textureView.getSurface();
try {
mPreviewRequestBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mCamera.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
mSessionCallback, null);
} catch (final Exception e) {
//...
}
Step 4: Make your preview extends beyond your viewport
This is then nothing related to the Camera2 API. We "crop" the preview by letting the SurfaceView
/ TextureView
extends beyond device's viewport.
First place your SurfaceView
or TextureView
in a RelativeLayout
.
Use the below to extend it beyond the screen, after you get the aspect ratio from step 2.
Note that in this case you probably need to know this aspect ratio before you even start the camera.
//Suppose this value is obtained from Step 2.
//I simply test here by hardcoding a 3:4 aspect ratio, where my phone has a thinner aspect ratio.
float cameraAspectRatio = (float) 0.75;
//Preparation
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenWidth = metrics.widthPixels;
int screenHeight = metrics.heightPixels;
int finalWidth = screenWidth;
int finalHeight = screenHeight;
int widthDifference = 0;
int heightDifference = 0;
float screenAspectRatio = (float) screenWidth / screenHeight;
//Determines whether we crop width or crop height
if (screenAspectRatio > cameraAspectRatio) { //Keep width crop height
finalHeight = (int) (screenWidth / cameraAspectRatio);
heightDifference = finalHeight - screenHeight;
} else { //Keep height crop width
finalWidth = (int) (screenHeight * cameraAspectRatio);
widthDifference = finalWidth - screenWidth;
}
//Apply the result to the Preview
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) cameraView.getLayoutParams();
lp.width = finalWidth;
lp.height = finalHeight;
//Below 2 lines are to center the preview, since cropping default occurs at the right and bottom
lp.leftMargin = - (widthDifference / 2);
lp.topMargin = - (heightDifference / 2);
cameraView.setLayoutParams(lp);
If you don't care about the result of Step 2, you can actually ignore Step 1 to Step 3 and simply use a library out there, as long as you can configure its aspect ratio. (It looks like this one is the best, but I haven't tried yet)
I have tested using my forked library. Without modifying any code of my library, I managed to make the preview fullscreen just by using Step 4:
And the preview just after taking a photo will not distort as well, because the preview is also extending beyond your screen.
But the output image will include area that you cannot see in the preview, which makes perfect sense.
The code of Step 1 to Step 3 are generally referenced from Google's CameraView.

- 5,179
- 3
- 34
- 68
-
it is work just removed renderscript functionality. Thank You, i regret for previous comment – Vasudev Vyas Aug 09 '19 at 04:53
-
step 4 solved the issue , without even going to 1 to 3 .. Thank You – Vaibhav singh Jul 29 '20 at 04:39
That's a common problem on some devices. I've noticed it mostly on samsung. You may use a trick with setting transformation on your TextureView
to make it centerCrop like ImageView
behaviour

- 164
- 8
-
no, that's not just on samsung devices I have checked it on Moto and Honor devices also. – Akash Bisariya Mar 22 '18 at 05:13
I also faced similar situation, but this one line solved my problem
view_finder.preferredImplementationMode = PreviewView.ImplementationMode.TEXTURE_VIEW
in your xml:
<androidx.camera.view.PreviewView
android:id="@+id/view_finder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
For camera implementation using cameraX you can refer https://github.com/android/camera-samples/tree/master/CameraXBasic

- 129
- 6
I figured out what was your poroblem. You were probably trying something like this:
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int j) {
cam.startPreview(surfaceTexture, i, j);
cam.takePicture();
}
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) { }
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { return false; }
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { }
});

- 3
- 5
-
Need more information. It is not clear from your answer what exactly is wrong with the code. – JCutting8 Mar 03 '19 at 15:31