I am making a Camera app in Android and have used the following function to get the preview size:
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
And I set the size like this:
Size s = getOptimalPreviewSize(parameters.getSupportedPreviewSizes(), w, h);
parameters.setPreviewSize(s.width, s.height);
But the problem is that when I run my app, the camera preview quality is really poor. How do i get the same preview quality as I get when I run my default camera app on my phone, in other words, I want a high resolution Camera preview in my app.
I am even not sure whether the preview size is the cause of this problem.
NOTE: The function to get the preview size is taken from sample programs from Android Docs.
That algorithm is not the greatest.
The default algorithm in my CWAC-Camera library is now:
public static Camera.Size getBestAspectPreviewSize(int displayOrientation,
int width,
int height,
Camera.Parameters parameters,
double closeEnough) {
double targetRatio=(double)width / height;
Camera.Size optimalSize=null;
double minDiff=Double.MAX_VALUE;
if (displayOrientation == 90 || displayOrientation == 270) {
targetRatio=(double)height / width;
}
List<Size> sizes=parameters.getSupportedPreviewSizes();
Collections.sort(sizes,
Collections.reverseOrder(new SizeComparator()));
for (Size size : sizes) {
double ratio=(double)size.width / size.height;
if (Math.abs(ratio - targetRatio) < minDiff) {
optimalSize=size;
minDiff=Math.abs(ratio - targetRatio);
}
if (minDiff < closeEnough) {
break;
}
}
return(optimalSize);
}
This:
Takes into account portrait versus landscape
Starts with the highest resolution previews and works its way down
Can be tailored via closeEnough
to opt for higher resolution as opposed to best matching the aspect ratio of the preview area
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With