Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Imagereader
- rotate90
- 190821
- 인증
- 알고리즘
- 190808
- Dopameter
- DeeplyBlue
- Android
- Kotlin
- 최교수님
- 190814
- DailyLog
- 190806
- Django
- 가사
- 190731
- YUV420_888
- 백준
- 190819
- 일기
- 도파미터
- Lyrics
- android.media.Image
- 안드로이드
- 190812
- 190801
- 190805
- 190813
- java
Archives
- Today
- Total
yuna dev history
[Android] ImageReader에서 YUV로 받은 Image 객체 회전rotate하기 본문
- 글 작성 이유: 구글에서 코드 찾다가 도저히 못 찾아서 그냥 바이트 단위로 쪼개서 rotate하도록 바꾸는 코드를 그냥 썼기 때문에 다른 사람은 고생하지 않았으면 해서.
- 전면 카메라 front camera에서 YUV420_888 이미지(android.media.Image 객체)를 받아온다. ImageReader에서 받아온 image 객체를 byte 버퍼로 바꾸고, 버퍼로 받아온 YUV를 반시계 방향으로 90도 회전시킨 형태의 바이트 버퍼로 변환한다.
- 필요했던 이유: 카메라를 회전해도 폰의 UI는 업데이트가 될지 몰라도 내부에서 실제로 받아오는 이미지의 버퍼 순서?는 변하지 않는다. 근데 내부 함수에서 회전한 버퍼?를 원했다.
- 주의해야 할 점 몇 가지
- YUV420_888 포맷을 유지한 채 android.media.image -> byte buffer로 바꾸는 과정
- YUV420_888 포맷은 Y가 Width*Height만큼 나오고 그 다음에 U와 V가 번갈아가며(순서는 UV순) 나오되 Width * (Height/2) 만큼만 나온다.
- Y 4개에 U, V가 각각 하나씩 매칭되는데, 예를 들어
Y1 Y2 Y3 Y4
Y5 Y6 Y7 Y8
U1 V1 U2 V2
라고 하면 Y1, Y2, Y5, Y6이 U1, V1과 매칭되는 식이다.
- Front Camera관련
- 프론트 카메라에서 X, Y Coordinate가 정해져있고, 이게 그냥 생각한 거랑 다르다
- (0, 0)이 오른쪽 맨 아래에 위치한다.
- 폰이 portrait으로 있다고 할 때, X 증가 방향은 세로, Y 증가 방향은 가로다
- 따라서 안에 코드를 찍어보면 폰이 portrait으로 있다고 할 때, Image Width가 폰의 세로 길이, image height 가 폰의 가로길이가 되며, image width > image hegiht인 상태가 된다.
- http://zhengrui.github.io/android-coordinates.html
- 위 사이트 그림을 참고하면 이해하기 쉽다
- android.media.Image 객체를 YUV420_888포맷을 유지한채 byte buffer로 바꾸는 코드는 여기저기 많이 있으니 여기서는 생략
아래 코드가 하는 일
android.media.Image객체는 YUV420_888 형태를 유지한 채로 byte buffer로 변환되어 있다고 할 때, 받아온 byte buffer를 반시계 방향 90도 돌려서 portrait의 byte buffer와 같은 순서인 (오른쪽 맨 아래에서부터 byte가 쌓이는 순서를 지켜가며) buffer가 되도록 rotate하기
public byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight) { byte [] yuv = new byte[imageWidth*imageHeight*3/2]; // Rotate the Y luma int i = 0; for (int x=0; x<imageWidth; x++) { for (int y=imageHeight-1; y>=0; y--) { yuv[i++] = data[imageWidth*y+x]; } } // Rotate the U and V color components for (int x=0; x<imageWidth; x+=2) { for (int y=imageHeight/2-1; y>=0; y--) { // copy U yuv[i++] = data[imageWidth*imageHeight+imageWidth*y+x]; // copy V yuv[i++] = data[imageWidth*imageHeight+imageWidth*y+x+1]; } } return yuv; }
비슷하게 코드를 짜면 180, 170도 같은 형태의 코드를 만들 수 있다.
무식하게 짰기 때문에 더 나은 코드가 있을 수 있으니 주의
'프로그래밍언어 > 안드로이드' 카테고리의 다른 글
[Android] Context란? (0) | 2019.06.26 |
---|