分享

android camera中的预览图片变形的解决办法

 深呼吸_DA 2014-08-25

摘要 之前处理相机模块的时候,遇到了一个问题,就是调用系统的camera的时候在拍照预览界面的时候看到的照片是变形的。不晓得大家有没有和我遇到一样的问题,后来发现是我的布局界面没有按对应的比例进行缩放导致的。后来参考了系统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的尺寸比例相同就行了。但是要注意的是:魅族手机貌似取不到这些值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@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();
        //释放资源
    }



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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;
     }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多