Android: reduce height of TextureView for camera preview - android

I'm studing this Google project with an example of Camera2 using: https://github.com/googlesamples/android-Camera2Basic
This example works perfectly. Now I want to have the area preview smaller than in this example; so I changed the ratio like this:
mTextureView.setAspectRatio(getScreenWidth(), getScreenHeight() - bottom_area_height);
but the result is bad... the preview doesn't have a good ratio now (is too stretched horizontally):
Have you got an idea guys?
Thank you very much!

You did get what you asked for, which is a different aspect ratio. Unfortunately, there's only one aspect ratio that's correct, since it needs to match that of the camera preview buffers.
If you want a smaller preview, you need to shrink it in both directions to maintain the correct aspect ratio. So if you update the layout to have a narrower space, and keep the aspect ratio the same, the height should also go down. Or reduce the height of the surrounding frame; in any case, the aspect ratio must remain what it is to have no stretching.
AutoFitTextureView isn't designed to crop the preview, which is the other option for avoiding stretching. That could be done by messing with the TextureView transform, but it does mean you're cutting off some of the view.

Related

How does PreviewView fill-scaling handle images which are higher resolution than the view?

When dealing with the PreviewView "FILL" scaling types (e.g. PreviewView.ScaleType.FILL_CENTER), the docs seem to imply that the image will not be scaled if it is higher resolution than the view.
Scale the preview, maintaining the source aspect ratio, so it fills the entire PreviewView, and center it in the view
In cases where the image is lower resolution than the view, I can understand why the image is scaled, as otherwise there would have to be black borders (i.e. would not fill the entire view), which FILL is guaranteeing will not be displayed. In cases where the image is higher resolution than the view, the preview image already fills the entire view (i.e. doesn't need to show black borders) so my assumption would be that the preview does not need to be scaled.
For example, your image is 1920x1080 and your view is 800x800, I would expect PreviewView to not scale the image and just crop an 800x800 square out of the centre of the existing image (using FILL_CENTER).
However when looking into the code I could not find any condition which actually stops scaling from happening when the resolution is higher.
For example:
preview.setScaleX(surfaceRectInPreviewView.width() / mResolution.getWidth());
preview.setScaleY(surfaceRectInPreviewView.height() / mResolution.getHeight());
preview.setTranslationX(surfaceRectInPreviewView.left - preview.getLeft());
preview.setTranslationY(surfaceRectInPreviewView.top - preview.getTop());
This code is after all the matrix transformations are done (which I don't fully understand), so I may be misinterpreting it. So I just wanted to validate my assumption about whether images are scaled if they are higher resolution than the view.
PreviewView is designed to display the largest possible FOV. If you wish to display a smaller FOV, you can take a look at the zooming APIs: https://developer.android.com/reference/androidx/camera/core/CameraControl#setZoomRatio(float)
The scaling in PreviewView is for getting rid of the black bars in case the aspect ratio of the preview does not match the aspect ratio of the view. It doesn't matter what resolutions they have.
In your example, the output image is 1920x1080 and the view is 800x800. For the FILL_* types, the output image will be scaled to fill the view, in which case it will be scaled to 1422x800, then the extras will be cropped out. For the FIT_* types, the output image will be scaled to fit the view, in which case it will be scaled to 800x450, and placed inside of the view.
Hope this helps. Please let me know if you have more questions.

Camera2 API preview aspect is broken

I am using the Camera2 API to setup an imagecapture fragment. I only want to use the camera in portrait mode. So i have set this line in the manifest in the fragment's parent activity:
android:screenOrientation="portrait"
Which locks the camera preview to portrait. However, the image aspect is just wrong. When the image is captured, there is no issues with the aspect, and the image looks as it should, but is still not in full screen. I suspect the camera output is stretched to fill the screen in my preview. How do i make both the preview and the captured image fill the entire screen and keep its aspect ratio like Snapchat does it?
I have been using the Google sample as my reference, and changed the AutoFitTextureView to match_parent in the XML layout file.
this is how it looks in normal portrait
and this is how it looks when i rotate the phone and is still in portrait mode
AutoFillTextureView attempts to keep the aspect ratio correct, but if you're changing its layout parameters, it may not be able to.
Do things work correctly if you don't make it 'match_parent'?
In general, Android UI elements will fill themselves with the input data, so you need to set the View's size to the right aspect ratio to avoid stretching.
For anyone who has been facing this issue like I was and if you have been using the google sample from before Jun 2017, then tweaking a line in your AutoFitTextureView should fix the preview's aspect ratio. It's as simple as changing "<" to ">" which you can see here.

How to get fullscreen textureview using camera2?

I am trying to get a full screen preview of the camera. I read through the documentation of camera2 which says Each Surface has to be pre-configured with an appropriate size and format (if applicable) to match the sizes and formats available from the camera device. Here is what I understand so far. Please correct me if any of my understanding is wrong:
The texture view and the preview buffer need to be the same aspect ratio. They can be different resolutions, but the aspect ratio must be the same if you don't want the preview to look distorted.
You should set the buffer size of the texture view to the optimally chosen preview size. camera2basic demo seems to confirm this with the line texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight().
The question I have is, once you match the aspect ratio and size of the texture view and the preview to be the same, how do you scale the texture view so that it fits fullscreen?
The camera2basic demo's configureTransform method seems to transform the TextureView to the preview size, but not make it full screen. How do I calculate the correct scale factor to make TextureView fullscreen?
You can just make your TextureView fill the screen in your Activity's layout. You'll then need to adjust the configureTransform() method to account for the aspect ratio difference between the full-screen TextureView and the closest-aspect preview size; basically you need to implement the usual letter- or pillar-boxing effect.
Of course, if there does happen to be a matching aspect ratio, you can use it directly, but this isn't too likely.

Android SurfaceView resize to fit screen 16:9

Hello! Is there a good way of having a 16:9 SurfaceView, and then resize it bigger until it touches a screen edge? (so the SurfaceView is at its biggest size and still 16:9 and not outside the screen)
I have heard it is called letterbox, but havn't found any tutorial about it.
Thanks
There are two relevant sizes, the size of the Surface and the size of the View.
The size of the Surface is determined by the size of the video being rendered to it. You can't change this. A 720p video will set the size to 1280x720.
The size of the View is determined by the layout code. This can be set from within your app.
The system compositor (SurfaceFlinger) will scale the contents of the Surface so they fit in the View. To avoid distortion, you want to maintain the same aspect ratio. You do this with a custom FrameLayout.
For an example, see how AspectFrameLayout is used in Grafika's video players, e.g. this chunk of code.

Round shaped image is elongated horizontally or vertically

I have to display a splash image which has a round shaped object (a Ball). The Layout for splash is a simple linear layout with just a single Image view to occupy the full screen.
Image : single image with the size of 1280 x 720.
When my splash screen is shown in the App, The round object is shown in different shape in different screen sizes. I hope the aspect ratio and the resolution is the cause for these elongated images.
Could you please suggest an idea / approach to solve this ?
Do I need to consider the aspect ratio or the resolution or both ?
Finally the ball should look like a ball in all the devices :)
Thanks in Advance.
1) Yes, by default Android will scale your image down to fit the ImageView, maintaining the aspect ratio. However, make sure you're setting the image to the ImageView using android:src="..." rather than android:background="...". src= makes it scale the image maintaining aspect ratio, but background= makes it scale and distort the image to make it fit exactly to the size of the ImageView. (You can use a background and a source at the same time though, which can be useful for things like displaying a frame around the main image, using just one ImageView.)
2)You should also see android:adjustViewBounds to make the ImageView resize itself to fit the rescaled image. For example, if you have a rectangular image in what would normally be a square ImageView, adjustViewBounds=true will make it resize the ImageView to be rectangular as well. This then affects how other Views are laid out around the ImageView.
You can change the way it default scales images using the android:scaleType parameter. By the way, the easiest way to discover how this works would simply have been to experiment a bit yourself! Just remember to look at the layouts in the emulator itself (or an actual phone) as the preview in Eclipse is usually wrong.
Reference : How to scale an Image in ImageView to keep the aspect ratio
set imageView property
scaleType="centerInside"
Add scaled versions of the image with the same file name under folders 'res->drawable','res->drawable-ldpi','res->drawable-hdpi' and under xhdpi "http://developer.android.com/guide/practices/screens_support.html#DesigningResources"

Categories

Resources