• [原]android camera中的预览图片变形的解决办法


    之前处理相机模块的时候,遇到了一个问题,就是调用系统的camera的时候在拍照预览界面的时候看到的照片是变形的。不晓得大家有没有和我遇到一样的问题,后来发现是我的布局界面没有按对应的比例进行缩放导致的。后来参考了系统camera中的代码解决了这个问题,特此记录下来。每部手机中设置了好几组预览图片的尺寸、以及实际图片的尺寸。只有当预览图的尺寸比例和实际图片的比例相同的时候就不会出现变形的情况。下面一组数据是我测试中记录的一组数据:

    02-09 19:00:40.831: D/tag(27507): pictureSizeValueString : 1280x960,1600x1200,2048x1536,2592x1456,2592x1936
    02-09 19:00:40.831: D/tag(27507): previewSizeValueString : 176x144,320x240,352x288,640x480,720x480,720x576,848x480,1280x720

    上面红色部分标记的都是具有相同比例的尺寸,都为4:3,而其他比例却不尽相同。故我们只要在初始化camera的时候给其设置好相同比例的预览图尺寸和实际图的尺寸,并且设置你的SurfaceView或者VideoView的尺寸比例相同就行了。但是要注意的是:魅族手机貌似取不到这些值。

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    try {
    //设置参数
    mCamera = Camera.open();
    //摄像头画面显示在Surface上
    mCamera.setPreviewDisplay(surfaceHolder);

    Parameters parameters = mCamera.getParameters();
    } catch (IOException e) {
    if (mCamera != null) mCamera.release();
    mCamera = null;
    }

    if (mCamera == null) {
    finish();
    return ;
    }
    updateCameraParameters();
    mCamera.startPreview();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
    int height) {
    try {
    //摄像头画面显示在Surface上
    mCamera.setPreviewDisplay(surfaceHolder);
    updateCameraParameters();
    mCamera.startPreview();
    } catch (IOException e) {
    if (mCamera != null) mCamera.release();
    mCamera = null;
    }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    mCamera.stopPreview();
    //关闭预览
    mCamera.release();
    //释放资源
    }



    private void updateCameraParameters() {
    if (mCamera != null) {
    Camera.Parameters p = mCamera.getParameters();

    long time = new Date().getTime();
    p.setGpsTimestamp(time);

    Size pictureSize = findBestPictureSize(p);
    p.setPictureSize(pictureSize.width, pictureSize.height);

    // Set the preview frame aspect ratio according to the picture size.
    Size size = p.getPictureSize();
    PreviewFrameLayout frameLayout = (PreviewFrameLayout) findViewById(R.id.frame_layout);
    frameLayout.setAspectRatio((double) size.width / size.height);

    Size previewSize = findBestPreviewSize(p);
    p.setPreviewSize(previewSize.width,previewSize.height);

    mCamera.setParameters(p);

    int supportPreviewWidth = previewSize.width;
    int supportPreviewHeight = previewSize.height;

    int srcWidth = getScreenWH().widthPixels;
    int srcHeight = getScreenWH().heightPixels;

    int width = Math.min(srcWidth, srcHeight);
    int height = width * supportPreviewWidth / supportPreviewHeight ;

    mSur.setLayoutParams(new FrameLayout.LayoutParams(height, width));//
    }
    }

    private Size findBestPictureSize(Camera.Parameters parameters) {
    int diff = Integer.MIN_VALUE;
    String pictureSizeValueString = parameters.get("picture-size-values");

    // saw this on Xperia
    if (pictureSizeValueString == null) {
    pictureSizeValueString = parameters.get("picture-size-value");
    }

    if(pictureSizeValueString == null) {
    return mCamera.new Size(getScreenWH().widthPixels,getScreenWH().heightPixels);
    }

    Log.d("tag", "pictureSizeValueString : " + pictureSizeValueString);
    int bestX = 0;
    int bestY = 0;


    for(String pictureSizeString : COMMA_PATTERN.split(pictureSizeValueString))
    {
    pictureSizeString = pictureSizeString.trim();

    int dimPosition = pictureSizeString.indexOf('x');
    if(dimPosition == -1){
    Log.e(TAG, "Bad pictureSizeString:"+pictureSizeString);
    continue;
    }

    int newX = 0;
    int newY = 0;

    try{
    newX = Integer.parseInt(pictureSizeString.substring(0, dimPosition));
    newY = Integer.parseInt(pictureSizeString.substring(dimPosition+1));
    }catch(NumberFormatException e){
    Log.e(TAG, "Bad pictureSizeString:"+pictureSizeString);
    continue;
    }

    Point screenResolution = new Point (getScreenWH().widthPixels,getScreenWH().heightPixels);

    int newDiff = Math.abs(newX - screenResolution.x)+Math.abs(newY- screenResolution.y);
    if(newDiff == diff)
    {
    bestX = newX;
    bestY = newY;
    break;
    } else if(newDiff > diff){
    if((3 * newX) == (4 * newY)) {
    bestX = newX;
    bestY = newY;
    diff = newDiff;
    }
    }
    }

    if (bestX > 0 && bestY > 0) {
    return mCamera.new Size(bestX, bestY);
    }
    return null;
    }

    private Size findBestPreviewSize(Camera.Parameters parameters) {

    String previewSizeValueString = null;
    int diff = Integer.MAX_VALUE;
    previewSizeValueString = parameters.get("preview-size-values");

    if (previewSizeValueString == null) {
    previewSizeValueString = parameters.get("preview-size-value");
    }

    if(previewSizeValueString == null) { // 有些手机例如m9获取不到支持的预览大小 就直接返回屏幕大小
    return mCamera.new Size(getScreenWH().widthPixels,getScreenWH().heightPixels);
    }
    Log.d("tag", "previewSizeValueString : " + previewSizeValueString);
    int bestX = 0;
    int bestY = 0;

    for(String prewsizeString : COMMA_PATTERN.split(previewSizeValueString))
    {
    prewsizeString = prewsizeString.trim();

    int dimPosition = prewsizeString.indexOf('x');
    if(dimPosition == -1){
    Log.e(TAG, "Bad prewsizeString:"+prewsizeString);
    continue;
    }

    int newX = 0;
    int newY = 0;

    try{
    newX = Integer.parseInt(prewsizeString.substring(0, dimPosition));
    newY = Integer.parseInt(prewsizeString.substring(dimPosition+1));
    }catch(NumberFormatException e){
    Log.e(TAG, "Bad prewsizeString:"+prewsizeString);
    continue;
    }

    Point screenResolution = new Point (getScreenWH().widthPixels,getScreenWH().heightPixels);

    int newDiff = Math.abs(newX - screenResolution.x)+Math.abs(newY- screenResolution.y);

    if(newDiff == diff)
    {
    bestX = newX;
    bestY = newY;
    break;
    } else if(newDiff < diff){
    if((3 * newX) == (4 * newY)) {
    bestX = newX;
    bestY = newY;
    diff = newDiff;
    }
    }
    }
    if (bestX > 0 && bestY > 0) {
    return mCamera.new Size(bestX, bestY);
    }
    return null;
    }

    protected DisplayMetrics getScreenWH() {
    DisplayMetrics dMetrics = new DisplayMetrics();
    dMetrics = this.getResources().getDisplayMetrics();
    return dMetrics;
    }



  • 相关阅读:
    java获取当前类的路径
    oracle 报错 column ambiguously defined
    各种在线api地址
    双击打开我的电脑 看不到硬盘盘符出现慢 安装百度云之后我的电脑卡
    Tomcat下获取当前类的路径中含有空格的解决方案
    win8解压版Tomcat startup.bat一闪而过的解决办法
    Shell基础篇shell简介之bash编程之参数说明
    Shell 基础篇介绍几个shell程序设计小知识
    Oracle数据仓库的分层管理器解决方案
    DataStage在RedHat Linux Enterprise 3上安装详细步骤(三)
  • 原文地址:https://www.cnblogs.com/tanlon/p/2344478.html
Copyright © 2020-2023  润新知