Programming/Android
카메라 촬영시 해상도 변경
유기농코더
2011. 10. 4. 10:34
class Preview extends SurfaceView implements SurfaceHolder.Callback { private static final int IMAGE_WIDTH = 1600; // 찍을 넓이 private static final int IMAGE_HEIGHT = 1200; // 찍을 높이 SurfaceHolder mHolder; Camera mCamera; OnPictureTakenCallback mCallback; Preview(Context context) { super(context); initHolder(); } // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. private void initHolder() { mHolder = getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public Preview(Context context, AttributeSet attrs) { super(context, attrs); initHolder(); } public Preview(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initHolder(); } public void setMode(int mode) { mMode = mode; } public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, acquire the camera and tell it where // to draw. mCamera = Camera.open(); try { mCamera.setPreviewDisplay(holder); Camera.Parameters parameters = mCamera.getParameters(); // 카메라에서 찍을 수 있는 모든 사이즈를 가지고 와서 그중에 하나를 선택한다. List<Size> sizes = parameters.getSupportedPictureSizes(); Size optimalSize; optimalSize = getOptimalPreviewSize(sizes, IMAGE_WIDTH, IMAGE_HEIGHT); parameters.setPictureSize(optimalSize.width, optimalSize.height); mCamera.setParameters(parameters); } catch (IOException exception) { mCamera.release(); mCamera = null; // TODO: add more exception handling logic here } } public void surfaceDestroyed(SurfaceHolder holder) { // Surface will be destroyed when we return, so stop the preview. // Because the CameraDevice object is not a shared resource, it's very // important to release it when the activity is paused. mCamera.stopPreview(); mCamera.release(); mCamera = null; } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // Now that the size is known, set up the camera parameters and begin // the preview. if (mCamera != null) { Camera.Parameters parameters = mCamera.getParameters(); // get the optimal preview size List<Size> sizes = parameters.getSupportedPreviewSizes(); Size optimalSize = getOptimalPreviewSize(sizes, w, h); parameters.setPreviewSize(optimalSize.width, optimalSize.height); mCamera.setParameters(parameters); mCamera.startPreview(); } } private Size getOptimalPreviewSize(List<Size> sizes, int width, int height) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) width / height; if (sizes == null) { return null; } Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = height; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) { continue; } if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } Log.i("optimal size", ""+optimalSize.width+" x "+optimalSize.height); return optimalSize; } private final Camera.PictureCallback jpeg = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { if (mCallback != null) { mCallback.onPictureTaken(data); } } }; public void takePicture() { camera.takePicture(null, null, jpeg); } public void restartPreview() { mCamera.startPreview(); } public void setOnPictureTakenCallback(OnPictureTakenCallback callback) { this.mCallback = callback; } public interface OnPictureTakenCallback { public void onPictureTaken(byte[] data); } }