我开发了一个小应用程序,用于全屏显示相机预览。我正在为此使用 Camera API。
这是 Activity 布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- This is the container for the camera preview screen -->
<FrameLayout android:id="@+id/camera_preview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
当设备处于纵向时,显示会垂直缩放以匹配设备屏幕的高度 - 因此纵横比与原生相机的纵横比不同。这是 2 张图片,可以更好地解释我的意思:
第一张图片是使用原生相机设备制作的。 第二张图片是用我的应用制作的,相机全屏显示 - 图像倾斜、拉伸(stretch)以适合屏幕。
我需要相机预览是全屏的,不管 getSupportedPreviewSizes()
方法给出的预览大小如何并且没有失真。
有没有办法做到这一点?当相机预览全屏时,有没有办法保持适当的纵横比?我希望这将由操作系统自动完成 - 裁剪图像以匹配请求的分辨率,同时保持纵横比,但这不会发生。
我试图使 SurfaceView
大于显示器(遵循这个问题:Fitting a camera preview to a SurfaceView larger than the display),但在我的情况下不行,因为我正在捕获快照(6 帧/秒) 并且这些不是用户在屏幕上看到的(帧包含所有相机预览,即使不是所有的都在屏幕上可见)。
我在这里发帖:https://www.dropbox.com/s/3d52xt8kazynsae/CameraFullScreen.7z?v=0mcn我所做的整个项目。
任何想法/解决方案对我来说都非常重要。非常感谢。
================================================ ==========================
更新由于 ss1271 答案:
我会稍微分析一下你上面为Samsung Galaxy Ace II写的分辨率。
我。屏幕分辨率:480x800 - 纵横比 3:5 = 0,6
二。 getSupportedPreviewSizes
- 我几乎可以肯定这些值来自后置摄像头。以下是这些分辨率的纵横比:
2560x1920 - 0,75
2560x1536 - 0,60
2048x1536 - 0,75
2048x1232 - 0,60
960x720 - 0,75
640x480 - 0,75
因此,您的方法将返回对应于 2560x1536 或 2048x1232 的 Size
- 这些具有与屏幕分辨率相同的纵横比并使用这些值不会扭曲图片。
对我来说,问题是我不能使用这么大的分辨率,因为我每秒捕获 6 帧,这些需要以较低的分辨率保存。
我将在下面展示来自 Samsung S2 设备的一些结果:
我。屏幕分辨率:480 x 800 - 纵横比 3:5 = 0,6
二。后置摄像头
一个)。 getSupportedPreviewSizes
:
800 / 480 - 480/800 = 0,60
800 / 450 - 450/800 = 0,56
720 / 480 - 0,66
640 / 480 - 0,75
352 / 288 - 0,81
320 / 240 - 0,75
176 / 144 - 0,81
b)。原生相机分辨率:
3264 / 2448 - 0,75 - not full screen
3264 / 1968 - 0,60 - FULL SCREEN (since has the same aspect ratio as device screen)
2048 / 1536 - 0,75 - not full screen
2048 / 1232 - 0,60 - FULL SCREEN (same aspect ratio as device screen)
800 / 480 - 0,60 - FULL SCREEN (same aspect ratio as device screen)
640 / 480 - 0, 75 - not full screen
三。前置摄像头
一个)。 getSupportedPreviewSizes
:
640 / 480 - 0,75
352 / 288 - 0,81
320 / 240 - 0,75
176 / 144 - 0,81
b)。原生相机未全屏显示,我无法选择分辨率 - 该选项已禁用。
对于 S2,后置摄像头,我想知道为什么 getSupportedPreviewSizes()
方法返回的分辨率与 native 摄像头的分辨率不同,或者 native 摄像头显示的分辨率是图片尺寸?我想知道为什么我没有 getSupportedPreviewSizes()
方法给出的 3264/1968、2048/1232 之类的选项?
:
最佳答案
简而言之,您可以全屏进行相机预览,但您需要自己在支持的预览尺寸中找出合适的尺寸,前提是您需要自定义相机预览。
对于您的问题,根据 Android Developers -- Camera
If you want to set a specific size for your camera preview, set this in the
surfaceChanged()
method as noted in the comments above. When setting preview size, you must use values fromgetSupportedPreviewSizes()
. Do not set arbitrary values in thesetPreviewSize()
method.
除了 getSupportedPreviewSizes()
提供的尺寸之外,您似乎无法手动传递所需的尺寸。仔细检查手机摄像头支持的尺寸,您会发现支持的尺寸比例可能与您的屏幕比例并不完全相同。
例如三星Galaxy Ace II有480x800分辨率的屏幕,通过读取getSupportedPreviewSizes()
返回的Size
,其相机支持:
2560x1920
2560x1536
2048x1536
2048x1232
960x720
640x480
如果您想正确全屏显示您的相机预览(不拉伸(stretch)),您需要计算、比较和应用这些支持的预览尺寸中的合适比例。
找到合适的预览尺寸的实现并不是那么复杂的事情。这样做的常用方法是这样的:
/**
* Calculate the optimal size of camera preview
* @param sizes
* @param w
* @param h
* @return
*/
private Size getOptimalSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
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)
{
// Log.d("CameraActivity", "Checking size " + size.width + "w " + size.height + "h");
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);
}
}
}
SharedPreferences previewSizePref;
if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
previewSizePref = getSharedPreferences("PREVIEW_PREF",MODE_PRIVATE);
} else {
previewSizePref = getSharedPreferences("FRONT_PREVIEW_PREF",MODE_PRIVATE);
}
SharedPreferences.Editor prefEditor = previewSizePref.edit();
prefEditor.putInt("width", optimalSize.width);
prefEditor.putInt("height", optimalSize.height);
prefEditor.commit();
// Log.d("CameraActivity", "Using size: " + optimalSize.width + "w " + optimalSize.height + "h");
return optimalSize;
}
你也可以做类似的事情来找出合适的相机尺寸(输出图片尺寸)。
注意:我从互联网上找到了上面代码的原始版本,并出于自己的目的进行了一些修改/优化。
如果这对你有用,请告诉我。
关于android - 全屏的相机显示/预览不保持纵横比 - 图像倾斜、拉伸(stretch)以适合屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16727836/