【发布时间】:2014-12-26 05:35:19
【问题描述】:
我添加了 FrameLayout,它在其中显示相机预览,但预览被拉伸了。
我已经尝试过https://*.com/a/19592492/1597844 中给出的解决方案,但这也无济于事。
你能帮忙看看我的代码有什么问题吗?
我得到的输出是 上图水平倾斜(纵向模式),下图垂直拉伸(横向模式) 我使用的代码是
mCamera = Camera.open(findBackFacingCamera());
Camera.Parameters parameters = mCamera.getParameters();
parameters.set("jpeg-quality", 100);
parameters.setPictureFormat(PixelFormat.JPEG);
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
mCamera.setParameters(parameters);
mPicture = getPictureCallback();
mPreview = new CameraPreview(myContext, mCamera);
backCameraPreview.removeAllViews();
backCameraPreview.addView(mPreview);
获得最佳预览尺寸的方法
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.05;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
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);
}
}
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;
}
我的 xml 看起来像这样
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="2">
<FrameLayout
android:id="@+id/dual_camera_capture_activity_ll_back_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@android:color/white"
android:orientation="horizontal"
android:padding="10dp" />
<FrameLayout
android:id="@+id/dual_camera_capture_activity_fl_front_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_weight="1"
android:background="@android:color/white"
android:orientation="horizontal"
android:padding="10dp" />
</LinearLayout>
这是我的 CameraPreview 类,即 SurfaceView
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private final Context mContext;
private SurfaceHolder mHolder;
private Camera mCamera;
private static String TAG = "Dual Camera";
private float mDist;
public CameraPreview(Context context, Camera camera) {
super(context);
mContext = context;
mCamera = camera;
mHolder = getHolder();
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surface created");
// The Surface has been created, now tell the camera where to draw the
// preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "surface destroyed");
this.getHolder().removeCallback(this);
}
public void refreshCamera(Camera camera) {
setCamera(camera);
if (mCamera != null) {
Display display = ((Activity) mContext).getWindowManager().getDefaultDisplay();
if (mHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
e.printStackTrace();
}
Camera.Parameters parameters = mCamera.getParameters();
if (display.getRotation() == Surface.ROTATION_0) {
mCamera.setDisplayOrientation(90);
}
if (display.getRotation() == Surface.ROTATION_90) {
}
if (display.getRotation() == Surface.ROTATION_180) {
}
if (display.getRotation() == Surface.ROTATION_270) {
}
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
mCamera = camera;
}
}
你能告诉我我做错了什么吗?
【问题讨论】:
-
如何匹配我的预览大小和布局大小?
-
Grafika (github.com/google/grafika) 中的一些示例;注意
AspectFrameLayout的使用。 -
任何更新@Roadies ??实际上我面临同样的问题。我正在使用surfaceView 和surfaceHolder 在一个屏幕上设置3 个摄像头盒。如果可用,请共享任何更新信息。
-
这个问题很老,但我评论是因为有人可以得到帮助here,对我来说@Hesam 的回答非常有用。
标签: android android-camera surfaceview android-orientation aspect-ratio