I wanted to preview and save a photo in a 4:3 aspect ratio, which is the standard and has the maximum resolution.
The camera plugin doesn't support changing the photo aspect ratio.
The Camera awesome plugin also has similar issues I think.
The adv_camera plugin has all the features but it doesn't support streaming images to run some AI-based analysis.
I'm not asking about the aspect ratio of the preview. The Aspect Ratio of the photo is saved is the problem.
Is there any way to get this done?
I'm having the same issue and I don't see a good solution.
I can offer 2 solutions that are both not optimal.
Use image_picker
Take the pictures in 16:9 and then crop them
Both more workarounds than solutions.
https://pub.dev/packages/image
var image = decodeImage(imageBytes);
image = copyResize(image, width: image.width, height: (image.width * 0.75).toInt());
imageBytes = encodePng(image); // encodeJpg/...
I am building a custom camera app. To make it look good, I have to adjust the camera preview dimensions based on the device's supported aspect ratio.
I searched on google and stackoverflow but couldn't find the solution I'm looking for. Please help me.
What I've tried :
There is an API method getSupportedPreviewSizes that returns a list of supported camera preview sizes. I tried using the getOptimalPreviewSize method suggested in this post but it's not returning the best preview size (or) aspect ratio.
My device details :
Honor Holy mobile phone with android 4.4.2.Screen dimensions : 1280 X 720
Correct aspect ratio : 4/3
But here's the twist. If I click a picture from my camera app and open it in the gallery app, the imageview scales automatically to the correct 4/3 aspect ratio. How does the android system detect this aspect ratio for the device? How can I also get it? If I can get the best aspect ratio for the device, I can resize my camera preview to look good.
I'm developing an Android application to take pictures and notice that the screen dimension ratio (480/800=0.6 for my HTC Desire X) is not the same as the picture resolution (1552/2592=0.5987) when I take picture by the default Camera application.The application has a fullscreen preview.
Does anyone know why there is this tiny difference ? And how does the default application handle this variance ?
Thanks !
When you are initializing the camera, you can set a number of different parameters. The relevant ones to this question are preview size and picture size. If you are using the standard method of taking pictures (the takePicture() method), the picture size will be set using setPictureSize() method for the camera parameters.
The preview size (you mentioned that you have fullscreen preview) is set independently of the picture size.
To set preview size, look at the supported preview sizes, and then set the preview size.
To set the picture size, look at the supported picture sizes, and then set the picture size.
I have a SurfaceView to display a live camera preview image in my Android app. The SurfaceView covers the whole width of the portrait screen, and a portion of the screen height.
I tried setting various preview sizes, so the preview had a distorted aspect ratio, short and fat or tall and skinny.
I printed debugs showing the actual preview display size, and the available preview camera sizes, so I could work out the aspect ratio error.
Screen size available for preview: w*h:1200*1646; Aspect ratio: 0.73
Rotation: 0; finalCameraRotation: 90; sideways: true
Supported Preview size: w*h:1080*1920: AspectRatio: 0.56: Error: -22.84%
Supported Preview size: w*h:768*1280: AspectRatio: 0.60: Error: -17.70%
...
Usually, I would pick the preview size with the lowest error in aspect ratio, but I was experimenting.
List<Camera.Size> ss = parameters.getSupportedPreviewSizes();
...
Camera.Size s = ss.get(pickOne);
parameters.setPreviewSize(s.width, s.height);
...
camera.setParameters(parameters);
...
camera.startPreview();
I measured the aspect ratio error of the preview display by pointing the camera at a white square and screenshotting it using Eclipse, then measuring the image of the white square in the screenshot using the photoshop ruler tool:.
I measured the x and y size of the square in screen pixels and computed 1-(y/x), and that should be the same as the aspect ratio error predicted in the debug log above.
I tried this on
Alcatel 995, Android 4.0.4
Samsung Note 2, Android 4.4.2
Google Nexus 7, Android 4.4.4
Google Nexus 5, Android 5.0
with various aspect ratios, as much as 25% in error from square, and in all of these, I measured aspect ratios in the preview within about 1% of that predicted. (There are errors, the camera might be not straight-on, it might be a bit out of focus...)
Except for the Google Nexus 7.
No matter what preview size I set for the Nexus 7, the measured aspect ratio was about 2% too tall, which just happens to be the best possible aspect ratio available:
Supported Preview size: w*h:768*1024: AspectRatio: 0.75: Error: 2.87%
It's as though some other program was coming and fixing the optimal preview size after I set it. I actually put in code to wait 10 seconds and read back the preview size from the camera, and it was the one I set, yet the display didn't reflect that. The display is always optimal no matter what preview size I set.
Is there something weird about preview sizes on Nexus 7?
I know that my setPreviewSize is doing something, because I can set the preview to 144*176px and then I see odd upsampling pixellation artefacts in the display. But it still has the nearly-corrrect aspect ratio!
I've just stumbled upon this problem myself. Reportedly, this happens to some devices, when camera's picture size and preview size parameters have different aspect ratios. In my case, my Nexus 7 appeared to always use a 4:3 preview, no matter what I'd set. Also, getPreviewSize() reported the size I'd set, not the one really used.
The solution is to find a picture size with an aspect ratio matching preview's one. So, get a list of supported picture sizes with getSupportedPictureSizes(), choose one with a proper width/height ratio and then setPictureSize(int width, int height). It worked for me like a charm :)
No matter what preview size I set for the Nexus 7, the measured aspect ratio was about 2% too tall, which just happens to be the best possible aspect ratio available:
Supported Preview size: w*h:768*1024: AspectRatio: 0.75: Error: 2.87%
[…] Is there something weird about preview sizes on Nexus 7?
Answer: yes, there's something weird …
The bug of the Nexus 7 is that all its preview sizes contain 4:3 image data, stretched to the size of the preview frames. In other words: The content of Nexus 7 viewfinder frames is always what you'd get by scaling a 1920×1440 px image1 (4:3) non-proportionally to the selected live camera preview size. Which means scaling by stretching as necessary, without cropping anything off.
Now here's why you observed the behaviour described in the question: by chance, your 1646×1200 of available screen space is nearly 4:3. So scaling the 4:3 image data provided by the Nexus 7 to that size will always result in the low aspect ratio error observed (2.87%). The intermediate step of scaling to preview size does not change anything, as it is undone by the following scaling to the available screen size.
It's a bug
You were lucky that your available screen size is 4:3, leading to proper previews from the Nexus 7. Everyone else however will fight with the fact that previews from Nexus 7 displayed in their indicated, natural size will appear distorted.
For example: the Nexus 7 reports many available preview sizes with aspect ratio that is not 4:3; let's take 1920×1080 (aspect ratio 1.78). Displaying the 4:3 frame content in a 1920×1080 rectangle then leads to stretched images.
So definitely there is a bug in the preview behaviour of the Nexus 7. The error seems to be that the 4:3 previews are meant for still images and 19:10 previews for video images, but the frames then erroneously always contain 4:3 image data. Or the other way around: the camera reports both types of preview sizes while its current mode only allows either 4:3 or 19:10 previews.
Workaround
There must be a proper way to work around this, as the Nexus 7 native camera app in video mode provides a 19:10 preview without distortions (means, it does not contain 4:3 image data).
As reported by #fljau in the other answer, setting the camera's still image capture resolution to match the aspect ratio of your selected preview will fix the issue. You can then display the camera live preview in its natural, reported size and will see no distortions of circular objects on the screen.
I just did this in Qt QML as follows:
Camera {
imageCapture {
resolution: "1920x1080"
}
viewfinder.resolution: "1920x1080"
}
It is not necessary to set Camera { captureMode: CaptureStillImage } for this to work. The still image resolution will affect the preview image data for any captureMode as a side effect (making it more clear that this is indeed a bug).
For a generic, model-independent solution in QML, you could go through the available viewfinder resolutions and then through the available still image resolutions and then set imageCapture.resolution as above to a value that matches the largest (resp. your desired) viewfinder resolution in aspect ratio.
Alternative workarounds
When you know the actual aspect ratio of the data inside the preview frames, you could show your camera live preview non-proportionally scaled to match this aspect ratio. Basically what the question author did accidentally (within a 2.87% error margin).
I also tried setting capture mode to "video" in the hopes that it will lead to 19:10 "video style" preview frame content does not work though. (For reference, I tried it in Qt QML with Camera { captureMode: Camera.CaptureVideo }.) That did not work.
1 A 1920×1440 px image is simply a 4:3 image large enough to cover the maximum supported preview size of 1920×1080 px. I made that size up for the sake of the argument so that scaling will not lose pixels you'd see in the preview.
Consider I want a picture of size 400*400, my camera supports picture size of 320*240,640*480,1024*768 etc...
My 1st question:
Which gives me better quality image in below two options
setPictureSize to 640*480. Once the picture is taken crop it to 480*480 then scale it into 400*400
setPictureSize to 1024*768. Once the picture is taken crop it to 768*768 then scale it into 400*400
My 2nd question:
I tested output of getSupportedPreviewSize in many android devices and in all devices it returns display resolution as one of the valid supported preview size. Is this true for all android devices?
My 3rd question
Does Preview Size affects quality of the image?
My 4th question
Consider I am using FrameLayout to preview camera, what is the relation between preview size and FrameLyoutsize. Should I change the dimension of the FrameLyout based on the size of the Preview
Thanks in advance. Sorry for asking lengthy question.
Why can't you crop it to 400x400? There is no way to tell which scaledown will turn out worse and a lot of factors apply. Generally the less scaling the better.
The getsupportedpreviewsizes will return at least one resolution in any android device with an API of 5 or greater: http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupportedPreviewSizes()
Note: The maximum resolution of the device is not always supported, but 640X480 is almost always supported.
Picture size is the image size while preview size is used for altering the image based on the current device orientation. This can scale the image more if it is not taken care of properly. In short, it can affect the quality, but not of the actual file: http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPictureSize(int, int)
Your frame layout may fill whatever area you have and will be stretched to fill that area. It should not affect quality of the actual picture taken.
1 The quality of 640x480 image "cropped" to 400x400 will be better than of 480x480 scaled down to 400x400. The downside is that you loose some filed of view. But you loose in anyway, when you turn a rectangular 4:3 picture into square, so probably you can afford even less field of view. If you really need the full field of view, then go for maximum resolution and use an image processing library (e.g. OpenCV) to scale the picture down.
2 Th answer is firm negative. Take a Nexus 10 for example. The screen is 2560 x 1600 pixels, while the highest preview size is 1920x1080 for back-facing, 1280x1024 for front-facing camera.