照相机技术(二)

  1 //定制拍照:
  2 public class MainActivity extends Activity {
  3     private Camera mCamera;
  4     private Preview mPreview;
  5 
  6     @Override
  7     protected void onCreate(Bundle savedInstanceState) {
  8         super.onCreate(savedInstanceState);
  9         // setContentView(R.layout.fragment_main);
 10         // 隐藏标题
 11         requestWindowFeature(Window.FEATURE_NO_TITLE);
 12         // 设置为全屏
 13         getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
 14         mPreview = new Preview(this);
 15         setContentView(mPreview);
 16     }
 17 
 18     @Override
 19     protected void onResume() {
 20         // TODO Auto-generated method stub
 21         super.onResume();
 22         // 第一步:打开照相机
 23         mCamera = Camera.open(0);
 24         mPreview.setCamera(mCamera);
 25     }
 26 
 27     // 释放焦点
 28     @Override
 29     protected void onPause() {
 30         // TODO Auto-generated method stub
 31         super.onPause();
 32         if (mCamera != null) {
 33             mCamera.release();
 34             mCamera = null;
 35             mPreview.setCamera(null);
 36         }
 37     }
 38 
 39     // 第三步:添加回调事件监听器SurfaceHolder.addCallback
 40     class Preview extends ViewGroup implements SurfaceHolder.Callback,
 41             OnClickListener {
 42         SurfaceView mSurfaceView;
 43         SurfaceHolder mHolder;
 44         Size mPreviewSize;
 45         List<Size> msupportedPreviewSizes;
 46         Camera mCamera;
 47         Context mContext;
 48 
 49         public Preview(Context context) {
 50             super(context);
 51             // TODO Auto-generated constructor stub
 52             mContext = context;
 53             mSurfaceView = new SurfaceView(context);
 54             addView(mSurfaceView);
 55             mHolder = mSurfaceView.getHolder();
 56             mHolder.addCallback(this);
 57         }
 58 
 59         public void setCamera(Camera camera) {
 60             mCamera = camera;
 61             if (mCamera != null) {
 62                 // 获得所有预览尺寸
 63                 msupportedPreviewSizes = mCamera.getParameters()
 64                         .getSupportedPictureSizes();
 65                 requestLayout();
 66 
 67             }
 68         }
 69 
 70         @Override
 71         public void surfaceCreated(SurfaceHolder holder) {
 72             // TODO Auto-generated method stub
 73             try {
 74                 if (mCamera != null) {
 75                     // 将Camera和SurfaceView关联
 76                     mCamera.setPreviewDisplay(holder);
 77                 }
 78             } catch (Exception e) {
 79                 // TODO: handle exception
 80             }
 81         }
 82 
 83         private PictureCallback mpPictureCallback = new PictureCallback() {
 84 
 85             @Override
 86             public void onPictureTaken(byte[] data, Camera camera) {
 87                 mCamera.startPreview();
 88                 File pictureFile = new File("/sdcard/image.jpg");
 89                 try {
 90                     FileOutputStream fos = new FileOutputStream(pictureFile);
 91                     fos.write(data);
 92                     fos.close();
 93                 } catch (Exception e) {
 94                     // TODO: handle exception
 95                 }
 96             }
 97         };
 98 
 99         @Override
100         public void surfaceChanged(SurfaceHolder holder, int format, int width,
101                 int height) {
102 
103             // 设置最佳预览尺寸
104             Camera.Parameters parameters = mCamera.getParameters();
105 
106             parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
107 
108             mCamera.setParameters(parameters);
109             mCamera.startPreview();
110         }
111 
112         @Override
113         public void surfaceDestroyed(SurfaceHolder holder) {
114             // TODO Auto-generated method stub
115             if (mCamera != null) {
116                 mCamera.stopPreview();
117             }
118         }
119 
120         @Override
121         protected void onLayout(boolean changed, int l, int t, int r, int b) {
122             // 使预览和实际窗口大小一致
123             if (changed && getChildCount() > 0) {
124                 final View child = getChildAt(0);
125                 int width = r - l;
126                 int height = b - t;
127                 int previewWidth = width;
128                 int previewHeight = height;
129                 if (mPreviewSize != null) {
130                     previewWidth = mPreviewSize.width;
131                     previewHeight = mPreviewSize.height;
132 
133                 }
134                 // 手机屏幕的宽高比大于采集图像的宽高比
135                 if (width * previewHeight > height * previewWidth) {
136                     final int scaledChildWidth = previewWidth * height
137                             / previewHeight;
138                     // child.layout((width - scaledChildWidth) / 2, 0,
139                     // (width + scaledChildWidth) / 2, height);
140                     child.layout(100, 100, 340, 240);// 设置照相框位置
141                 } else {
142                     final int scaledChildHeight = previewWidth * width
143                             / previewWidth;
144                     child.layout(0, (height - scaledChildHeight) / 2, width,
145                             (height + scaledChildHeight) / 2);
146                 }
147             }
148 
149         }
150 
151         private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
152 
153             double ASPECT_TOLERANCE = 0.1;
154             double targetRatio = (double) w / h;
155             if (sizes == null) {
156                 return null;
157             }
158             Size optimalSize = null;
159             double minDiff = Double.MAX_VALUE;
160             int targetHeight = h;
161             for (Size size : sizes) {
162 
163                 double ratio = (double) size.width / size.height;
164                 if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {
165                     continue;
166                 }
167                 if (Math.abs(size.height - targetHeight) < minDiff) {
168                     optimalSize = size;
169                     minDiff = Math.abs(size.height - targetHeight);
170                 }
171 
172             }
173             if (optimalSize == null) {
174                 minDiff = Double.MAX_VALUE;
175                 for (Size size : sizes) {
176 
177                     if (Math.abs(size.height - targetHeight) < minDiff) {
178                         optimalSize = size;
179                         minDiff = Math.abs(size.height - targetHeight);
180                     }
181 
182                 }
183             }
184 
185             return optimalSize;
186 
187         }
188 
189         @Override
190         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
191             // TODO Auto-generated method stub
192             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
193             int width = resolveSize(getSuggestedMinimumWidth(),
194                     widthMeasureSpec);
195             int height = resolveSize(getSuggestedMinimumHeight(),
196                     heightMeasureSpec);
197             setMeasuredDimension(width, height);
198             if (msupportedPreviewSizes != null) {
199                 mPreviewSize = getOptimalPreviewSize(msupportedPreviewSizes,
200                         width, height);
201             }
202 
203         }
204 
205         @Override
206         public void onClick(View v) {
207             // TODO Auto-generated method stub
208             mCamera.takePicture(null, null, mpPictureCallback);
209         }
210 
211     }
212 
213 }
原文地址:https://www.cnblogs.com/my334420/p/6921369.html