浅析Android Camera开发中的三个尺寸和三种变形 (贡献一个自适配Picturesize和Previewsize的工具类)

经常听人问Camera开发中,各种变形问题,今天有空就在此梳理总结下。

三个尺寸:

1、Surfaceview的尺寸

Surfaceview是用来预览Camera的,当它全屏时就是Screen的大小。

2、Picturesize的尺寸

这是拍照后的PictureSize尺寸。

3、Previewsize的尺寸

这是预览时帧数据的尺寸。

三种变形:

1、预览画面的物体长宽失真。原因是Surfaceview和Previewsize的长宽比率不一致,就会导致预览画面上失真。因为camera在显示时会将预览帧数据缩放成Surfaceview大小,当比率不一致必然会物体变形。至于这个缩放算法可能不同手机会有区别。

2、拍照后照片上物体变形。

3、点击拍照瞬间,预览画面上会突然变形然后恢复到正常预览。

2、3两种变形都是因为Previewsize和Picturesize的长宽比率不一致所致。总之一句话,为了保证图片不是真,要保证预览Surfaceview、Previewsize、Picturesize的长宽比率要一直。如果Surfaceview是全屏的话,要获取屏幕长和宽得到比率。

为此我写了一个工具类,获得合适的Picturesize和Previewsize,名字为:MyCamPara.java。

  1. package org.yanzi.util; 
  2.  
  3. import java.util.Collections; 
  4. import java.util.Comparator; 
  5. import java.util.List; 
  6.  
  7. import android.hardware.Camera; 
  8. import android.hardware.Camera.Size; 
  9. import android.util.Log; 
  10.  
  11. public class MyCamPara { 
  12.     private static final String tag = "yan"; 
  13.     private CameraSizeComparator sizeComparator = new CameraSizeComparator(); 
  14.     private static MyCamPara myCamPara = null; 
  15.     private MyCamPara(){ 
  16.          
  17.     } 
  18.     public static MyCamPara getInstance(){ 
  19.         if(myCamPara == null){ 
  20.             myCamPara = new MyCamPara(); 
  21.             return myCamPara; 
  22.         } 
  23.         else{ 
  24.             return myCamPara; 
  25.         } 
  26.     } 
  27.      
  28.     public  Size getPreviewSize(List<Camera.Size> list, int th){ 
  29.         Collections.sort(list, sizeComparator); 
  30.          
  31.         int i = 0; 
  32.         for(Size s:list){ 
  33.             if((s.width > th) && equalRate(s, 1.33f)){ 
  34.                 Log.i(tag, "最终设置预览尺寸:w = " + s.width + "h = " + s.height); 
  35.                 break; 
  36.             } 
  37.             i++; 
  38.         } 
  39.  
  40.         return list.get(i); 
  41.     } 
  42.     public Size getPictureSize(List<Camera.Size> list, int th){ 
  43.         Collections.sort(list, sizeComparator); 
  44.          
  45.         int i = 0; 
  46.         for(Size s:list){ 
  47.             if((s.width > th) && equalRate(s, 1.33f)){ 
  48.                 Log.i(tag, "最终设置图片尺寸:w = " + s.width + "h = " + s.height); 
  49.                 break; 
  50.             } 
  51.             i++; 
  52.         } 
  53.  
  54.         return list.get(i); 
  55.     } 
  56.      
  57.     public boolean equalRate(Size s, float rate){ 
  58.         float r = (float)(s.width)/(float)(s.height); 
  59.         if(Math.abs(r - rate) <= 0.2) 
  60.         { 
  61.             return true; 
  62.         } 
  63.         else{ 
  64.             return false; 
  65.         } 
  66.     } 
  67.      
  68.     public  class CameraSizeComparator implements Comparator<Camera.Size>{ 
  69.         //按升序排列 
  70.         public int compare(Size lhs, Size rhs) { 
  71.             // TODO Auto-generated method stub 
  72.             if(lhs.width == rhs.width){ 
  73.             return 0; 
  74.             } 
  75.             else if(lhs.width > rhs.width){ 
  76.                 return 1; 
  77.             } 
  78.             else{ 
  79.                 return -1; 
  80.             } 
  81.         } 
  82.          
  83.     } 


对上面这个工具类注释如下:

1,是个单例模式类。调用示例:

  1. Size pictureS = MyCamPara.getInstance().getPictureSize(pictureSizes, 800); 
  2.             myParam.setPictureSize(pictureS.width, pictureS.height); 


2,程序首先对预览尺寸的list进行升序排序,因为实际中发现,有的手机提供的是升序有的是降序。

3,通过equalRate(Size s, float rate)保证Size的长宽比率。一般而言这个比率为1.333/1.7777即通常说的4:3和16:9比率。

4、在getPreviewSize()函数里增加判断if((s.width > th) && equalRate(s, 1.33f)),除保证比率外,还保证用户需要设置的尺寸宽度最小值。这个大家根据需要随便改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值