Reputation: 5597
I'm having an issue with the camera on Android, basically when I take a photo with the Camera class, the taken output picture actually shows more than the preview. The best way to put it would be the preview is cropped. How would I fix this?
I've run the app on Samsung Galaxy S4, Samsung Galaxy S3, HTC One M8 and Nexus One and all exhibit this same issue. (All running Android 4.0 ICS)
The camera preview is full screen in an Activity with no Action Bar and the status bar hidden.
The camera i'm trying to create is portrait so I've set displayOrientation to 90.
The code I use for determining preview size and output photo size is as follows (I believe the problem is most likely here somewhere):
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);
}
public static Camera.Size getLargestPictureSize(CameraHost host,
Camera.Parameters parameters,
boolean enforceProfile) {
Camera.Size result=null;
for (Camera.Size size : parameters.getSupportedPictureSizes()) {
// android.util.Log.d("CWAC-Camera",
// String.format("%d x %d", size.width, size.height));
if (!enforceProfile
|| (size.height <= host.getDeviceProfile()
.getMaxPictureHeight() && size.height >= host.getDeviceProfile()
.getMinPictureHeight())) {
if (result == null) {
result=size;
}
else {
int resultArea=result.width * result.height;
int newArea=size.width * size.height;
if (newArea > resultArea) {
result=size;
}
}
}
}
if (result == null && enforceProfile) {
result=getLargestPictureSize(host, parameters, false);
}
return(result);
}
Size comparator class:
private static class SizeComparator implements
Comparator<Camera.Size> {
@Override
public int compare(Size lhs, Size rhs) {
int left=lhs.width * lhs.height;
int right=rhs.width * rhs.height;
if (left < right) {
return(-1);
}
else if (left > right) {
return(1);
}
return(0);
}
}
This is using cwac-camera and using SimpleCameraHost with no changes.
Any help is appreciated!
Upvotes: 0
Views: 879
Reputation: 1006869
How would I fix this?
If you are using the full-bleed preview, the preview will be cropped in most cases, as the aspect ratio of the CameraView
is unlikely to match the aspect ratio of the preview frames.
Quoting the documentation:
The original default behavior of
CameraFragment
andCameraView
was to show the entire preview, as supplied by the underlyingCamera
API. Since the aspect ratio of the preview frames may be different than the aspect ratio of theCameraView
, this results in a "letterbox" effect, where the background will show through on one axis on the sides.The new default behavior is to completely fill the
CameraView
, at the cost of cropping off some of the actual preview frame, what is known as "full-bleed preview" (stealing some terminology from the world of print media).To control this behavior:
Have your
CameraHost
returntrue
orfalse
fromuseFullBleedPreview()
Or, call
useFullBleedPreview()
on yourSimpleCameraHost.Builder
, passing in aboolean
value to use by default.Note that the pictures and videos taken by this library are unaffected by
useFullBleedPreview()
. Hence, ifuseFullBleedPreview()
returnstrue
, the picture or video may contain additional content on the edges that was not visible in the preview.
Upvotes: 1