首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >预览摄像头HTC-One裁剪图像

问预览摄像头HTC-One裁剪图像
EN

Stack Overflow用户
提问于 2014-12-29 21:58:46
回答 1查看 96关注 0票数 0

我在我的应用程序上使用了一个自定义的相机预览,它在几乎所有的设备上都工作得很好,对于HTC来说,我得到了一个糟糕的切割,原始照片与预览显示在顶部的不匹配。

它只在这个设备上发生,这是我的预览相机的代码和正在发生的事情的图片。

提前感谢任何人能给我的帮助。

代码语言:javascript
复制
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

private final String TAG = "CameraPreview";

private SurfaceHolder mHolder;
private Camera mCamera;
private Context context;
private Camera.Size mPreviewSize;
private List<Camera.Size> mSupportedPreviewSizes;

public CameraPreview(Context context) {
    super(context);
    this.context = context;
    mHolder = getHolder();
    mHolder.addCallback(this);
}

public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {

        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        for (Camera.Size str : mSupportedPreviewSizes) {
            Log.e(TAG, str.width + "/" + str.height);
        }

        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);

    if (mSupportedPreviewSizes != null) {
        mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
    }

    float ratio;
    if (mPreviewSize.height >= mPreviewSize.width) {
        ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
    } else {
        ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;
    }

    setMeasuredDimension(width, (int) (width * ratio));
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (mHolder.getSurface() == null) {
        // preview surface does not exist
        return;
    }

    // stop preview before making changes
    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        // ignore: tried to stop a non-existent preview
    }

    // set preview size and make any resize, rotate or reformatting changes here
    // start preview with new settings
    try {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

        mCamera.setParameters(parameters);
        mCamera.setDisplayOrientation(90);
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();

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

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}

public void setFlash(String flashMode) {
    Camera.Parameters params = mCamera.getParameters();
    params.setFlashMode(flashMode);
    mCamera.setParameters(params);
}

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;


    for (Camera.Size size : sizes) {
        double ratio = (double) size.height / size.width;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
            continue;

        if (Math.abs(size.height - h) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - h);
        }
    }

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - h) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - h);
            }
        }
    }

    return optimalSize;
}

public void switchCamera(Camera camera) {
    Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    if (display.getRotation() == Surface.ROTATION_0) {
        camera.setDisplayOrientation(90);
    } else if (display.getRotation() == Surface.ROTATION_270) {
        camera.setDisplayOrientation(180);
    }

    setCamera(camera);
    try {
        camera.setPreviewDisplay(mHolder);
    } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
    }
}
}

​

​

EN

回答 1

Stack Overflow用户

发布于 2014-12-31 19:46:06

摄像头预览大小和图片大小是两个不同的参数,可以通过setPictureSize()和setPreviewSize()接口更新。但是如果用户不改变这些大小,它将使用默认值。

在这种情况下,您通过基于某个纵横比计算最佳预览大小来更新预览大小。但您没有更新图片大小,因此它将使用默认图片大小。

如果图片大小和预览大小的纵横比不同,捕获的图像看起来肯定不同于预览。因此,还可以通过计算具有与预览大小相同的纵横比的最佳图片大小来更新图片大小。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27690298

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档