[안드로이드] 실시간 SurfaceView 화면 캡쳐하기
어플리케이션 제작 중에 SurfaceView에 CameraPreview를 이용하여 카메라를 제어하는 프로그래밍 중
실시간으로 SurfaceView를 캡쳐해야하는 코드가 필요해 처리하는 과정 등을 정리하여 포스팅합니다.
SurfaceView는 일반적인 함수로 캡쳐하면 검은 화면만 출력되기 때문에...
여러가지 찾아본 후 적용되는 코드로 설명하곘습니다.
CameraPreview로 SurfaceView에 카메라 화면을 출력할 때, 실시간으로 사진파일이 필요할 때 사용합니다.
[CameraPreview.java]
public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback {
... 중략 ...
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
... 중략 ...
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(new Camera.PreviewCallback(){
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// 현재 SurfaceView를 JPEG Format으로 변경
Camera.Parameters parameters = camera.getParameters();
int w = parameters.getPreviewSize().width;
int h = parameters.getPreviewSize().height;
int format = parameters.getPreviewFormat();
YuvImage image = new YuvImage(data, format, w, h, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
Rect area = new Rect(0, 0, w, h);
image.compressToJpeg(area, 100, out);
Bitmap bm = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());
byte[] currentData = out.toByteArray();
... 중략 ...
}
}
}
기본 코드입니다.
CameraView class에서 SurfaceHolder.Callback을 implements하고
surfaceChanged() 에서 mCamera.setPreviewCallback을 호출합니다.
onPreviewFrame 메소드는 CameraPreview에서 실시간으로 호출되는 함수입니다.
위 코드는 현재 SurfaceView 화면을 캡쳐해서 JPEG Format으로 만들어주는 코드입니다.
여기서 JPEG 파일을 PNG 파일로 바꾸는 방법입니다.
... 위 코드로 부터 계속 ...
int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation);
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1 // 이미지 사이즈 리스케일(2의 지수 승으로 해야 처리속도 빠름; 1,2,4,8,16...; 필요시)
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
// RGB_565 : 16bit Bitmap, ARGB_8888 : 32bit Bitmap, 4444는 저품질이라 추천안함
Bitmap bitmap = BitmapFactory.decodeByteArray(currentData, 0, currentData.length, options);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
// bitmap src, start x, start y, width, height, 회전, Flag
// Bitmap 이미지를 surfaceView 좌표로 변환
bitmap = GetBinaryBitmap(bitmap); // bitmap 이진화 처리
//bitmap을 byte array로 변환
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); // 100 수치 변경해서 품질(Quality) 변경
currentData = stream.toByteArray();
// 이후 해당 Byte Array로 파일 저장 및 처리...
... 중략 ....
}
}
}
조금 복잡할 수도 있는 코드입니다.
한줄씩 주석 포함해서 해석하면서 코드 작성하시면 쉽게 처리 가능할 것 같습니다.
PNG(Bitmap으로) 파일 저장하는 방법은 Google에 많이 있고 또 예제코드가 있기 때문에 생략하겠습니다.
이상 CameraPreview에서 카메라 화면을 SurfaceView에 출력하고 그 화면을 캡쳐하는 방법에 대해 알아보았습니다.
질문 사항은 댓글로 남겨주세요!!
* 참고 글 :
'Android' 카테고리의 다른 글
안드로이드 핀치 줌 구현 - 멀티 터치 (0) | 2018.08.29 |
---|---|
안드로이드 이미지 뷰 여백 없애기 (0) | 2018.08.28 |
안드로이드 카메라 줌 기능 구현 (1) | 2018.08.27 |
[안드로이드] 비트맵 이진화 처리 (1) | 2018.08.25 |
안드로이드 특수키 제어하기 (3) | 2018.08.23 |
[Android] 안드로이드 내부 저장소 텍스트 파일 읽기 및 쓰기 (2) | 2018.08.21 |
[Android] 안드로이드 SurfaceView 카메라 연동하기 (3) | 2018.08.20 |
안드로이드 EditText 사용법 정리 (0) | 2018.08.20 |