Android 全屏相机 - 同时保持相机选择的比例 [英] Android full screen camera - while keeping the camera selected ratio

查看:37
本文介绍了Android 全屏相机 - 同时保持相机选择的比例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在尝试构建类似于 Instagram 相机屏幕的东西.即允许用户拍摄 square 照片.在执行此操作时,U.i 必须能够让用户在 fullScreen 模式下看到相机.我们想强制用户以 portrait 模式

We are trying to build something similar to Instagram Camera screen. i.e allow the user taking square photos. While doing it out U.i must be able to let the user see the camera on fullScreen mode. We want to force the user to take an image in a portrait mode

我们正在计算 camera 可用的 best 比率

We are calculating the best ratio available from camera by

   private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio = (double) h / w;

    if (sizes == null) {
        return null;
    }

    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    for (Camera.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 (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}

全屏显示.

public FrameLayout setCameraLayout(int width, int height) {
     float newProportion = (float) width / (float) height;
     // Get the width of the screen
     int screenWidth =     this.customCameraActivity.getWindowManager().getDefaultDisplay()
            .getWidth();
     int screenHeight =    this.customCameraActivity.getWindowManager().getDefaultDisplay()
            .getHeight();
      float screenProportion = (float) screenWidth / (float) screenHeight;
      // Get the SurfaceView layout parameters
      ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)preview.getLayoutParams();


     if (newProportion > screenProportion) {
        lp.width = screenWidth;
        lp.height = (int) ((float) screenWidth / newProportion);
     } else {
        lp.width = (int) (newProportion * (float) screenHeight);
        lp.height = screenHeight;
    }

    //calculate the amount that takes to make it full screen (in the `height` parameter)
    float propHeight = screenHeight / lp.height;

    //make it full screen(
    lp.width = (int)(lp.width * propHeight);
    lp.height = (int)(lp.height * propHeight);

    frameLayout.setLayoutParams(lp);
    return frameLayout;

}

setCameraLayout 调用者

OnCreate 来自 Activity 和之后的 surfaceChanged

 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
                           int height) {
    if (getHolder().getSurface() == null) {
        return;
    }
    try {
        cameraManager.getCamera().stopPreview();
    } catch (Exception e) {
        // tried to stop a non-existent preview
    }

    try {
        Camera.Parameters cameraSettings = cameraManager.getCamera().getParameters();

        cameraSettings.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        this.cameraView.setCameraLayout(mPreviewSize.width, mPreviewSize.height);
        cameraManager.getCamera().setParameters(cameraSettings);
        cameraManager.getCamera().setPreviewDisplay(holder);

        cameraManager.getCamera().startPreview();
    } catch (Exception e) {
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}

目标

手机上的全屏相机预览.

Goal

Fullscreen camera preview on phone.

现在我们得到了没有失真的预览,这是好!,它具有与 phone 相同的 height 以及也好!.但是!preview 的宽度比 phone 宽度 大(当然)所以事实证明相机的中心是不在手机的中央.我们考虑过的可能解决方案:

Now we are getting the preview with no distortion which is GOOD! and it has the same height as the phone as well which is also GOOD!. But! the width of the preview is bigger than the phone width (of-course) so it turns out the the center of the camera is not on the center of the phone. Possible solutions we have thought about:

  1. 移动布局左到负位置,使预览中心在屏幕中央.
  2. crop 布局并仅绘制 新预览 的中心,该中心应该对 手机屏幕
  3. 可见
  1. move the layout left to negative position to make the preview center in the center of the screen.
  2. crop the layout and draw only the center of the new preview that should be visible to the phone screens

有什么想法可以解决这个问题吗?

非常感谢!:)

推荐答案

我通过设置 SurfaceView 的重力成功地使预览居中:

I managed successfully center the preview by setting gravity of SurfaceView:

FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(wid, hei);
lp.gravity = Gravity.CENTER;
mSv.setLayoutParams(lp);

代码片段取自 此处,如果您有耐心破译它,欢迎您使用该代码.我想我正在解决类似的问题(预览旋转、扭曲、适合/填充)

The code snippet is taken from here, and you're welcome to use the code if you have the patience to decipher it. I think I was solving similar issues (preview rotation, distortion, fit-in/fill)

祝你好运.

这篇关于Android 全屏相机 - 同时保持相机选择的比例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆