본문 바로가기

Programming/Android

카메라 촬영시 해상도 변경

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);
	}

}

'Programming > Android' 카테고리의 다른 글

안드로이드 개발 환경 구축하기  (0) 2012.06.07