Camera display doesn't maintain aspect ratio/seems skewed
Okay, I just found the answer to my own question.
The way I solved it was by going fullscreen with my application:
requestWindowFeature(Window.FEATURE_NO_TITLE);
This makes a little bit of sense, as I guess we can not use just any resolution as the preview size on the camera. I guess it will internally snap to the closest allowed resolution/aspect ratio and it doesn't do any smart things like cropping the image to match the requested resolution while maintaining aspect ratio. In my case I was displaying a title bar while the source image was fullscreen and then downsized to fit on the screen.
I think it is kind of stupid that the aspect ratio is not maintained and images are not cropped by default,
Camera PreviewView is stretched in some Android devices
Solved!
I had a default values for the BufferSize of my texture, which just are restarted when I inicializated a new Session or after change the after ratio. But the Width and Height values for the texture were not updated with the ratio, so it becomes streched again and again.
I solved it changing my defaultbufferSize with the PreviewSizes which I update always that i change the ratio.
public void createCameraPreviewSession(Size previewsize, Surface recordingSurface) {
try {
if (mCaptureSession != null) {
mCaptureSession.stopRepeating();
mCaptureSession.close();
mCaptureSession = null;
}
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
List<Surface> surfaces = new ArrayList<Surface>();
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());
;
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
.......
Preview image from the camera is stretched
Does your screen aspect ratio correspond to your preview's frame ratio?
Assure correct aspect ratio in onMeasure:
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
if (this.mAspectRatio == 0) {
super.onMeasure(widthSpec, heightSpec);
return;
}
int previewWidth = MeasureSpec.getSize(widthSpec);
int previewHeight = MeasureSpec.getSize(heightSpec);
int hPadding = getPaddingLeft() + getPaddingRight();
int vPadding = getPaddingTop() + getPaddingBottom();
previewWidth -= hPadding;
previewHeight -= vPadding;
boolean widthLonger = previewWidth > previewHeight;
int longSide = (widthLonger ? previewWidth : previewHeight);
int shortSide = (widthLonger ? previewHeight : previewWidth);
if (longSide > shortSide * mAspectRatio) {
longSide = (int) ((double) shortSide * mAspectRatio);
} else {
shortSide = (int) ((double) longSide / mAspectRatio);
}
if (widthLonger) {
previewWidth = longSide;
previewHeight = shortSide;
} else {
previewWidth = shortSide;
previewHeight = longSide;
}
// Add the padding of the border.
previewWidth += hPadding;
previewHeight += vPadding;
// Ask children to follow the new preview dimension.
super.onMeasure(MeasureSpec.makeMeasureSpec(previewWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(previewHeight, MeasureSpec.EXACTLY));
}
from this project
Showing Camera Preview not taking full screen
This is working as designed, though what you want will be in the 0.6.0 version.
Quoting an upcoming version of the project README
:
The default behavior of CameraFragment
and CameraView
is to show the entire
preview, as supplied by the underlying Camera
API. Since the aspect ratio of
the preview frames may be different than the aspect ratio of the CameraView
,
this results in a "letterbox" effect, where the background will show through on
one axis on the sides.
If you want the preview to completely fill the CameraView
, at the cost of
cropping off some of the actual preview frame, have your CameraHost
return true
from useFullBleedPreview()
.
Note that the pictures and videos taken by this library are unaffected byuseFullBleedPreview()
. Hence, if useFullBleedPreview()
returns true
, the
picture or video may contain additional content on the edges that was not
visible in the preview.
Support for useFullBleedPreview()
will be in version 0.6.0 of the library, though the source code for it is already pushed to the repo and is available in the master
branch. You are welcome to keep tabs on this issue for further developments.
Related Topics
Start Activity with an Animation
How to Set the Focus (And Display the Keyboard) on My Edittext Programmatically
Nexus 7 Not Visible Over Usb via "Adb Devices" from Windows 7 X64
How to Retrieve Key Alias and Key Password for Signed APK in Android Studio(Migrated from Eclipse)
Get Launchable Activity Name of Package from Adb
What Is the Correct Way to Specify Dimensions in Dip from Java Code
How to Calculate Dp from Pixels in Android Programmatically
Handling Back Button in Android Navigation Component
How to Get Toolbar from Fragment
Android Imageview Adjusting Parent's Height and Fitting Width
Do I Need 14 Different Layouts to Support All Android Devices
How to Call Rest API from an Android App
Android Studio: New Project VS New Module
Android Preferences: How to Load the Default Values When the User Hasn't Used the Preferences-Screen
Gradle and Multi-Project Structure
Extract Black and White Image from Android Camera's Nv21 Format