【问题标题】:Camera PreviewSize Automatically Change when takePicture拍照时相机预览大小自动改变
【发布时间】:2015-01-05 17:53:45
【问题描述】:

我在 SurfaceChanged 方法上使用 getOptimalPreviewSize() 方法。当我点击拍照按钮 PreviewSize 返回第一个尺寸并返回时使用它后。

它必须保持相同的预览大小。为什么会变?

这里代码:

PictureCallback myPictureCallback_JPG = new PictureCallback(){
   @Override
   public void onPictureTaken(byte[] data, Camera camera) {
       File pictureFile = getOutputMediaFile();
       if (pictureFile == null){               
           return;
       }           

       try {

           FileOutputStream fos = new FileOutputStream(pictureFile);
           fos.write(data);
           fos.close();

        } catch (FileNotFoundException e) {
            Log.d("Method.PictureCallBack", "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d("Method.PictureCallBack", "Error accessing file: " + e.getMessage());
        }

        camera.startPreview();
  }
};

ShutterCallback myShutterCallback = new ShutterCallback(){
       @Override
       public void onShutter() {}
};

PictureCallback myPictureCallback_RAW = new PictureCallback(){
       @Override
       public void onPictureTaken(byte[] arg0, Camera arg1) {}
};

public void takePicture() {
    mCamera.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG);

}

【问题讨论】:

  • 我找不到任何解决方案。

标签: android android-camera surfaceview


【解决方案1】:

预览尺寸和图片尺寸不同。使用 getPreviewSize() 获取屏幕上预览的尺寸。并且使用 getPictureSize() 可以获取调用 takePicture 时将要拍摄的图片的确切尺寸。

【讨论】:

  • 显然,所选 PictureSize 和 PreviewSize 的纵横比不匹配。选择匹配的尺寸是个好主意(例如预览:1280x720,图片:3640x2048)。确保活动相机同时支持 PictureSize 和 PreviewSize。当宽高比不匹配时,在不同设备上观察到许多故障。
【解决方案2】:

我知道这可能是一个迟到的答案,但无论如何,我想分享我对这个问题的解决方案。

为了解决这个问题,您需要做的事情如下:

  1. 使用 Camera.Params.getSupportedPictureSizes() 方法获取所有支持的图片尺寸。

  2. 找到最可接受的大小并将它们存储在临时容器中(ArrayList 可以正常工作)

  3. 通过Camera.Params.setPictureSize(width, height)找到您要使用的尺寸,并实际为相机提供您要使用的尺寸

  4. 这并不是真正的第四步,而是第三步的补充。 在大多数情况下,您的相机默认设置的方向不正确,如果没有事先调整图像也会如此。 所以,我强烈建议你使用 Camera.Params.setRotation(angle) 用于图片方向更改,Camera.Params.setDisplayOrientation(angle) 用于预览方向更改。

下面是处理图片大小的代码:

public static final float CAMERA_SIZE_RATIO_CALIBRATION = 0.1f;

private Camera.Size findTheBestPictureSize() {
    List<Camera.Size> supportedSizes = mCamera.getParams().getSupportedPictureSizes();
    ArrayList<Camera.Size> acceptableSizes = new ArrayList<Camera.Size>();

    Camera.Size foundSize = null;
    Camera.Size tmpSize = null;
    float desiredRatio = (mDisplaySize[0] * 1f / mDisplaySize[1]);
    float calculatedRatio;
    float deltaRatio = 0f;

    //Looking for the most acceptable sizes
    int itemCount = supportedSizes.size();
    for(int i = 0; i < itemCount; i++) {
        tmpSize = supportedSizes.get(i);

        calculatedRatio = (shouldSizeDimensionsBeFlipped ? (tmpSize.height * 1f / tmpSize.width) 
                : (tmpSize.width * 1f / tmpSize.height));

        deltaRatio = Math.abs(calculatedRatio - desiredRatio);

        if(deltaRatio <= CAMERA_SIZE_RATIO_CALIBRATION) {
            acceptableSizes.add(tmpSize);
        }
    }

    //Looking for the greatest acceptable size
    itemCount = acceptableSizes.size();
    for(int i = 0; i < itemCount; i++) {
        tmpSize = acceptableSizes.get(i);

        if(foundSize == null) {
            foundSize = tmpSize;
            continue;
        }

        if(tmpSize.width > foundSize.width && tmpSize.height > foundSize.height) {
            foundSize = tmpSize;
        }
    }

    return foundSize;
}

其中 shouldSizeDimensionsBeFlipped 是一个布尔值,它确定我们是否需要考虑从相机中获取的尺寸是否翻转(其中宽度作为高度,高度作为宽度)(我们只需要这样做,如果默认相机方向是除 0 和 270 以外的所有方向)

我希望这能帮助遇到同样问题的人:)

【讨论】:

    猜你喜欢
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多