Apresentação realizada na disciplina de Aplicações Corporativas como cumprimento do curso de Sistemas para Internet do Unipê (Centro Universitário de João Pessoa)
What Is Java | Java Tutorial | Java Programming | Learn Java | EdurekaEdureka!
This Edureka "What Is Java" tutorial will help you in understanding the various fundamentals of Java in detail with examples. Below are the topics covered in this tutorial:
1) What is Java?
2) Where is Java used?
3) Features of Java
4) Java Environment
5) How does Java work?
6) Data Types in Java
7) Operators in Java
8) Functions in Java
9) Object Oriented Concepts in Java
Dart is the language that is used to write and code out Flutter Applications. It's the first step to building your own flutter app. So join us 5th March at 5 PM to learn all about Dart, the most popular language used for building Flutter Applications.
Agenda:
• Basic Syntax, Data Types and Variables
• Conditional Statements and loops
• Functions and Exception Handling
• Class, Objects, Reference and Instance Variables
• Inheritance and Method Overriding
• Arrays, Sets and HashSet, Maps and HashMaps
Apresentação realizada na disciplina de Aplicações Corporativas como cumprimento do curso de Sistemas para Internet do Unipê (Centro Universitário de João Pessoa)
What Is Java | Java Tutorial | Java Programming | Learn Java | EdurekaEdureka!
This Edureka "What Is Java" tutorial will help you in understanding the various fundamentals of Java in detail with examples. Below are the topics covered in this tutorial:
1) What is Java?
2) Where is Java used?
3) Features of Java
4) Java Environment
5) How does Java work?
6) Data Types in Java
7) Operators in Java
8) Functions in Java
9) Object Oriented Concepts in Java
Dart is the language that is used to write and code out Flutter Applications. It's the first step to building your own flutter app. So join us 5th March at 5 PM to learn all about Dart, the most popular language used for building Flutter Applications.
Agenda:
• Basic Syntax, Data Types and Variables
• Conditional Statements and loops
• Functions and Exception Handling
• Class, Objects, Reference and Instance Variables
• Inheritance and Method Overriding
• Arrays, Sets and HashSet, Maps and HashMaps
Java Programming | Java Tutorial For Beginners | Java Training | EdurekaEdureka!
This Edureka Java Programming tutorial will help you in understanding the various programming fundamentals of Java in detail with examples. Below are the topics covered in this tutorial:
1) Variables
2) Data Types in Java
3) Operators in Java
4) Conditional Statements in Java
5) Loops
6) Arrays and Strings
7) Functions in Java
8) Classes and Objects in Java
Presentation covers the concept of hybrid mobile application development as well the examples, A better way to start developing applications for all platform in amount of just one, The future of application development.
IGC 2017과 시작해요 언리얼 2017에서 발표를 한 '오버턴 VR 개발기 - 1인 개발 3년차 리포트' 입니다.
오버턴을 개발하면서 있었던 이야기를 담고 있고
VR 게임을 개발하기 위한 노하우를 최대한 이야기하였습니다.
그러면서 1인 독립 개발을 하면서 느꼈던 점들을
발표하였으니 도움이 되셨으면 좋겠습니다.
피드백은 아래 SNS로 부탁드립니다.
https://twitter.com/Hanguny
Java Programming | Java Tutorial For Beginners | Java Training | EdurekaEdureka!
This Edureka Java Programming tutorial will help you in understanding the various programming fundamentals of Java in detail with examples. Below are the topics covered in this tutorial:
1) Variables
2) Data Types in Java
3) Operators in Java
4) Conditional Statements in Java
5) Loops
6) Arrays and Strings
7) Functions in Java
8) Classes and Objects in Java
Presentation covers the concept of hybrid mobile application development as well the examples, A better way to start developing applications for all platform in amount of just one, The future of application development.
IGC 2017과 시작해요 언리얼 2017에서 발표를 한 '오버턴 VR 개발기 - 1인 개발 3년차 리포트' 입니다.
오버턴을 개발하면서 있었던 이야기를 담고 있고
VR 게임을 개발하기 위한 노하우를 최대한 이야기하였습니다.
그러면서 1인 독립 개발을 하면서 느꼈던 점들을
발표하였으니 도움이 되셨으면 좋겠습니다.
피드백은 아래 SNS로 부탁드립니다.
https://twitter.com/Hanguny
Devtree에서 진행했던 Lightmapping workshop 1일차 자료.
Full version은 다음 링크에서 받으실수 있습니다 : http://illu.tistory.com/1178
비엘북스에서 출간된 유니티, 언리얼 그리고 VR편을 보시면 좀 더 이해가 쉽습니다. 본 슬라이드 셰어 내용은 기본적인 내용만 설명되어있습니다.
아래의 9권 책 리뷰를 포함하고 있습니다.
리팩토링 코드 품질을 개선하는 객체지향 사고법
빅데이터의 충격 (거대한 데이터의 파도가 사업 전략을 바꾼다)
헤드 퍼스트 데이터 분석 (당신을 최고의 데이터 분석가로 이끌어줄 마법 같은 학습서)
왓슨 인간의 사고를 시작하다
소프트웨어 누가 이렇게 개떡같이 만든 거야
앱만장자 (부를 거머쥔 인디 개발자들의 성공 비법)
애자일 마스터 (프로젝트 인셉션 추정과 계획 그리고 실행)
읽기 좋은 코드가 좋은 코드다 (더 나은 코드를 작성하는 간단하고 실전적인 테크닉)
프로그래머, 열정을 말하다
2. 1. Camera
2. Color Space
3. Camera API
4. Surface
5. Texture
6. OpenGL
7. Case Study
목차
참고 : 이 PT를 바탕으로 강의를 통해 설명을 하기 위해 만들어 졌
던 자료이기에 PT만으로 이해가 안가는 부분이 있을 수 있음.
참고한 소스는 아래와 같다.
https://android.googlesource.com/
https://github.com/google/grafika
https://github.com/CyberAgent/android-gpuimage
3. 1.Camera
1. Camera
3 / 14
Android 에서 가장 인기 있는 앱, 서비스는 카메라 기반 서비스들이 많다.
카메라 앱은 멀티미디어 서비스의 결정체이기도 기본적으로 알아야 할 것들이 많다.
카메라 앱을 만들기 위한 기초에 대해서 간략히 정리하는 것이 이 PT의 목표이다.
Android에서는 5.0 Lollipop 부터 기존의 Camera API를 대체할 수 있는 강력한 Camera2 API를 제공하고 있
지만, 다양한 버전을 모두 서비스 해야하는 환경에서 Camera2 API는 아직 전폭적으로 사용되고 있지 못하다.
심지어 5.0, 5.1 일부 단말기에서도 제대로 지원을 못하는 상황이 있어 제조사, 단말기, Android 버전에 따른 파
편화 관리가 어렵기에 당분간은 Camera API를 그대로 사용할 것 같다.
따라서 현재 모든 내용은 Camera API를 기반으로 설명된다.
4. 1.Camera 4 / 14
Android system architecture
간단히 Java API 로 제공되는
android.hardware.Camera API를 사용하면,
물리적인 카메라가 어떤 단계를 거쳐 오는지 생각 못할
수 있는데, Android system architecture를 보면 정말
많은 단계를 통해 개발자에게 Camera의 정보가 오는
것을 확인할 수 있다.
출처 :
https://developer.android.com/guide/platform/in
dex.html?hl=ko
5. 1.Camera 5 / 14
Camera architecture
Camera 만 다시 한번 보면
좀 더 자세히 확인할 수 있다.
출처 :
https://source.android.com/devices/camera/
6. 1.Camera 6 / 14
Kernel driver
실제 카메라 하드웨어와 HAL과 상호 작용을 하는 단계로, 카메라와 드라이버는 YV12, NV21 이미지 형식을
지원해야만 카메라의 미리보기와 비디오 녹화가 가능하다.
YV12, NV21에 대해서는 뒤의 색공간에서 다시 한번 소개한다.
HAL
실제 카메라 하드웨어를 제어하는 Kernel driver를 카메라 서비스가 직접 다루지 않고 중간 층인
HAL( Hardware Abstraction Layer )을 통해 접근하도록 정의된 표준 인터페이스 이다.
출처 : https://source.android.com/devices/camera/
7. 1.Camera 7 / 14
Camera service
안드로이드 프레임워크 frameworks/av/services/camera/libcameraservice/CameraService.cpp 에 위치하
여 HAL과 통신하는 실제 코드이다.
출처 : https://source.android.com/devices/camera/
8. 1.Camera 8 / 14
Binder IPC proxies
frameworks/av/camera 에 위치한 3가지 바인더 클래스가 존재한다.
- ICameraService
- ICamera
- ICameraClient
출처 : https://source.android.com/devices/camera/
9. 1.Camera 9 / 14
Native framework, JNI, Application framework
frameworks/av/camera/Camera.cpp는 우리가 어플리케이션에서 사용하는 android.hardware.Camera
API에 대응되는 native code이다.
android.hardware.Camera API에서는 JIN를 통해 Camera Service는 IPC binder proxies를 이용하여 접근
한다.
출처 : https://source.android.com/devices/camera/
10. 1.Camera 10 / 14
Camera Pipeline
Raw Bayer Input 은 Camera Sensor를 통해 전달된
이미지를 의미한다. 현재 대부분의 폰에서 사용되는
Camera sensor는 한 개의 소자가 모든 색을 받아들이
는 구조가 아니라 R,G,B 각각의 색에 반응하는 소자들
을 조합하여 사용한다. 따라서 우리가 보는 RGB이미지
로 보기 위한 변환이 필요하다.
출처 :
https://source.android.com/devices/camera/came
ra3_requests_hal
http://www.cis.upenn.edu/~danielkh/files/2013_
2014_demosaicing/2013_RTF_demosaicing_1.pdf
11. 1.Camera 11 / 14
Camera Pipeline
Android 에서는 Camera Sensor의 이미지를 그대로
전달하는게 아니라, 생각보다 많은 보정 단계를 거친후
에 전달된다.
기본적으로 사용되는 3A Algorithms 은 아래의 3가지
의 앞 글자를 따온 것이다.
- Auto-focus
- Auto-exposure
- Auto-whitebalance
12. 1.Camera 12 / 14
Hot Pixel Correction
Hot Pixel은 모든 것이 검은 환경에서도 발생하는 흰색
의 픽셀을 의미한다. 이는 카메라 센서에서 노이즈와 과
부하등으로 발생하기도 하기에 제일 처음 처리하는 이
미지 단계가 이를 보정하는 것이다.
주변 픽셀들등의 정보를 이용해 보간법(interpolation)
으로 수정한다.
13. 1.Camera 13 / 14
Demosaic
앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이
미지로 복원하는 과정을 의미한다.
14. 1.Camera 14 / 14
Demosaic
앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이
미지로 복원하는 과정을 의미한다.
Bayer filter samples
Red Green Blue
Reconstructed
15. 1.Camera 15 / 14
Demosaic
앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이
미지로 복원하는 과정을 의미한다.
16. 1.Camera 16 / 14
Noise Reduction
DSLR과 같은 전문 카메라와 달리 카메라 센서의 크기가
제한적이고, 렌즈의 밝기도 어두운 경우가 많아 저조도
환경(어두운 환경), 확대한 환경 등에서 품질이 떨어지
기에 이를 보완하기 위한 방법이다.
17. 1.Camera 17 / 14
Shading Correction
잘못된 그림자를 보정하는 부분이다.
18. 1.Camera 18 / 14
Edge Enhancement
이미지의 엣지부분의 대비(contrast)를 높혀서 선명하
게 보이도록 하는 작업이다.
19. 1.Camera 19 / 14
Output
Camera에서 제공하는 Output은 3가지 이다.
- RAW
- JPEG
- YUV
20. 1.Camera 20 / 14
Raw
Camera2 API 부터 지원한다.
Raw 이미지는 앞서 거치는 Image Processing을 거치
지 않은 Camera Sensor의 결과물이다.
따라서 전문적으로 다른 Image Processing을 거치면
다른 JPEG을 만들어 낼 수 있다. 그래서 주로 전문가들
이 사용한다.
21. 1.Camera 21 / 14
JPEG
Camera API의 takePicture 메서드를 이용하면 받을 수
있는 결과물로 폰의 Camera가 지원하는 최고의 해상도,
퀄리티의 이미지를 받아 볼 수 있다.
해당 포맷은 Preview로 제공되지 않고, takePicture 메
서드로만 받을 수 있다.
22. 1.Camera 22 / 14
YUV
Camera API의 startPreview를 한 이후에 제공되는
preview(실시간의 Camera Sensor에 전달되는 이미지
들…)는 해당 포맷으로 제공된다.
JPEG에 비해 해상도가 떨어진다.
대부분의 폰에서 폰의 Display 해상도 ( QHD, FHD,
HD 정도)의 해상도 이하로 제공된다.
23. 2. Color Space
2. Color Space
23 / 14
색, 색 공간(色空間, color space)
색 공간에 대한 이해는 필수이다.
동영상 쪽을 전혀 해보지 않았으면,
색공간 == RGB 인줄 알지만, 카메라에서 주로 쓰이는 색공간은 RGB가 아니다.
따라서 혼동이 많이 발생하기에, 색공간에 대한 이해를 정확히 해야 한다.
24. 2.Color Space 24 / 14
색 (Color)
사전적 정의 :
가시광선의 명암과 분광 조성에 대한 시감각 또는 색감각, 색감각을 일으키는
빛 또는 색자극, 색자극을 일으키는 물체의 특성.
사람은 약 107,000가지의 색을 구별할 수 있음.
25. 2.Color Space 25 / 14
색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma)
색상(hue)
색깔의 질로도 표현하는데, 우리가 쉽게 색이라고 하면 생각하는 가장 중요한 색의 성질이다.
보면 안다.
26. 2.Color Space 26 / 14
색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma)
명도(lightness)
눈이 느끼는 밝기의 차이.
먼셀표색계에서는 흰색을 명도 10, 검정색을 0으로 하고
그 사이의 단계를 10단계 등분하여 번호를 매겨 사용한다.
같은 단계의 명도라 하더라도 색상에 따라
더 밝게, 어둡게 보일 수 있다.
27. 2.Color Space 27 / 14
색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma)
채도(Chroma, Saturation)
색이 보다 선명할수록 채도가 높다고 말하며
회색이나 흰색 또는 검정과 같은 무채색에 가까울수록 채도가 낮다고 말한다.
채도가 높은 색을 말할 때는 흔히 '짙다'고 표현하고,
반대로 채도가 낮은 색을 말할 때는 흔히 '흐리다'는 표현을 사용한다.
예를 들어 짙은 노랑, 흐린 노랑과 같이 표현할 수 있다.
28. 2.Color Space 28 / 14
Color space(색공간)
색 공간(色空間, color space)은 색 표시계(color system)를 3차원으로 표현한 공간 개념이라고
사전적으로 정의한다. 3차원인 이유는?
앞에서 설명한 색의 3가지 속성인 색상(hue), 명도(lightness), 채도(chroma)을 각각의 축으로
3차원 공간으로 표현한 것이다. 미술시간에 많이 봤을 먼셀 색입체를 보면 이해가 쉽다.
29. 2.Color Space 29 / 14
RGB
RGB 색 공간은 색을 혼합하면 명도가 올라가는 가산 혼합 방식으로 색을 표현한다.
( 빛은 더할수록 명도가 올라가서 모든 색을 다 섞으면 흰색이 된다는 것을 초등학교에서 배웠을 것이다. )
RGB 가산혼합의 삼원색은 빨강(Red), 녹색(Green), 파랑(Blue)을 뜻한다.
RGBA은 RGB와 동일하며, 알파(Alpha)라는 투명도(투과도)를 추가한 것.
RGB 색 공간은 삼원색에 해당하는 세 가지 채널의 밝기를 기준으로 색을 지정한다.
RGB 색 공간은 웹 색상 표현의 기본 원리이다.
30. 2.Color Space 30 / 14
CMYK
CMYK 색 공간은 인쇄과정에서 쓰이는 감산 혼합 방식으로,
(실제 미술시간에 빛과 달리 물감을 섞으면 섞을수록 검정색이 되는 것을 경험해봤을 것이다. )
흰 바탕에 네 가지 잉크의 조합으로 색을 나타내는 것을 말한다.
색을 혼합하면 명도가 낮아지기에 감산 혼합이라고 한다.
CMYK는 인쇄에 쓰이는 4가지 색은 옥색(Cyan), 자청색(Magenta), 노랑(Yellow), 검정(Black)을 뜻한다.
31. 2.Color Space 31 / 14
HSV
HSV 색 공간은 색상(Hue), 채도(Saturation), 명도(value)를 기준으로 색을 구성하는 방식이다.
감산 혼합이나 가산 혼합보다 색상의 지정이 직관적이기 때문에 시각 예술에서 자주 쓰인다.
32. 2.Color Space 32 / 14
Color space (색 공간)
모든 색 공간이 표현하는 색이 같은데, 방법이 다른게 아니라 색 공간에 따라 표현하는 색의 범위가 다르다.
이 점을 반드시 이해해야 한다. ( 아래의 면적이 클수록 표현할 수 있는 색이 많은 색 공간이다. )
33. 2.Color Space 33 / 14
YUV (=YCbCr)
흑백TV시절의 방송 인프라를 사용하여, 한 방송으로 컬러TV와 흑백TV를 다 볼 수 있도록 고안되었다.
흑백TV에서 이용되던 정보에 부수적으로 컬러정보를 추가하여 사용하여, 인프라의 큰 교체없이 컬러TV를 볼
수 있게 되었다.
34. 2.Color Space 34 / 14
YUV (=YCbCr)
실제 적용 예를 보면, 원래 컬러인 이미지가 흑백인 Y와 추가적인 컬러 정보 UV로 구성되어 있다.
Original Y’
U V
35. 2.Color Space 35 / 14
YUV (=YCbCr)
자연상에서 가장 많은 색인 Green에 더 많은 공간을 두어서
모든 색이 동일한 범위를 갖는 것에 비해 효율적인 구조를 만듦.
UV
U : Ranges from Red to Yellow
V : Ranges from Blue to Yellow
36. 2.Color Space 36 / 14
YUV (=YCbCr)
YUV는 밝기(Luminance)인 Y성분과 색상(Chrominance)인
U(Cb)와 V(Cr) 성분으로 구성하여 픽셀을 표현하는 방식.
일반적인 RGB 방식에 비하여 작은 용량(대역폭)으로 전송이 가능
1 pixel 표시 크기 비교
ARGB = 32bits ( 4bytes )
YUV411 = Y : 8 bit + U : 2 bit + V : 2 bit = 12bits
극단적으로 ARGB를 사용해 1 pixel을 32bits 로 전송하는 것을 12bits로 전송할 수 있으니 62.5%의 적어 지
금까지도 많은 곳에서 사용 되는 것이다.
37. 2.Color Space 37 / 14
YUV (=YCbCr)
이렇게 극단적으로 적은 정보로 전송할 수 있는 이유는?
흑백의 명암을 나타내는 Y정보에 데이터의 절반을 사용하는 이유는 사람의 눈은 밝기 변화를 느끼는 간상세포
는 9천만 개 이상 존재하는데 비하여 색상을 인식하는 원추세포는 약 600만 개 정도에 불과하기 때문이다.
따라서, 사람의 시각은 밝기의 변화에 비하여 색상의 변화에는 둔감하다는 특성을 보이게 된다.
이에 따라 많은 영상 시스템은 밝기 정보와 색상의 정보를 분리하여 별도로 부호화 하도록 하여 필요에 따라 압
축 효율을 높인다.
원추세포는 3가지
L 원추세포(ρ세포) : 빨간색
M 원추세포(Г세포) : 청녹색과 노란색
S 원추세포(β세포) : 파란색
각각 원추세포의 비율이 다르다.
빨강 40 : 녹색 20 : 파랑 1
38. 2.Color Space 38 / 14
YUV (=YCbCr)
YUV는 YUV422, YUV420, YUV411 등의 포맷이 있는데,
이러한 표현은 아래와 같이 각 구성값의 비트 할당수에서 비롯한다.
즉 YUV422은 Y:U:V = 4:2:2 이다.
YUV는 RGB 처럼 한 개의 픽셀 개념으로 이해하면 안됨!
39. 2.Color Space 39 / 14
YUV (=YCbCr)
YUV는 한 개의 픽셀 개념으로 이해하면 안되며, 기존 TV의 주사방식을 생각해보면 이해하기 쉬움
기존 TV 주사방식: 비월 주사 방식(Interlace scanning)
하나의 영상을 홀수와 짝수 가로줄로 나뉜 것을 번갈아가며 표시하는 영상의 표시 방식이다.
41. 2.Color Space 41 / 14
YUV (=YCbCr)
각 구성값의 비트 할당수로도 구분되지만, YUV를 어떤 순서로 배열해서 사용하는지에 따라도 구분된다.
YUV422 : YUV를 아래와 같은 순서로 사용한다.
YUV420 : 구성요소 별로 모아 놓았다.
43. 2.Color Space 43 / 14
YUV (=YCbCr)
Single Frame YUV420 : 16 Bits per pixel
IMC1 IMC3
44. 2.Color Space 44 / 14
YUV (=YCbCr)
Single Frame YUV420 : 12 Bits per pixel
IMC2 IMC4
45. 2.Color Space 45 / 14
YUV (=YCbCr)
Single Frame YUV420 : 12 Bits per pixel
YV12 NV12
46. 2.Color Space 46 / 14
NV12/NV21
NV12 : YUV420 과 비슷한 개념이나, 표현 방식이 다름
For 1 NV12 pixel: YYYYYYYY UVUV
For a 2-pixel NV12 frame: YYYYYYYYYYYYYYYY UVUVUVUV
For a 50-pixel NV12 frame: Y*8*50 (UV)*2*50
For a n-pixel NV12 frame: Y*8*n (UV)*2*n
NV21 : NV12와 비슷하나 UV의 순서가 바뀌어 VU로 출력됨
47. 2.Color Space 47 / 14
RGB <-> YUV 변환
문제는 우리가 주로 쓰는 색공간은 결국 RGB이고,
픽셀단위로 조작이 필요하거나 후처리를 위해 변환이 필요한 경우가 발생한다.
RGB <-> YUV는 색공간이 다르기에 정확히 1대1 대응이 되지 않는다.
수많은 방법들이 있으나, 아래와 같은 수학식으로도 변환이 될 수 있다.
From RGB to YUV
Y = 0.299R + 0.587G + 0.114B
U = 0.492 (B-Y)
V = 0.877 (R-Y)
It can also be represented as:
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
From YUV to RGB
R = Y + 1.140V
G = Y - 0.395U - 0.581V
B = Y + 2.032U
48. 2.Color Space 48 / 14
RGB <-> YUV 변환
이를 코드로 보면 아래와 같다.
이 코드는 실제로 사용되면 안된다. (엄밀히 말하면, YUV-> RGB 변환이 CPU에서 실행되면 안된다.)
RGB와 YUV를 변환하는 것이 얼마나 큰 비용의 연산인지 감을 잡기위해 작성한 코드이다.
void YUVfromRGB(double& Y, double& U, double& V, const double R, const double G, const double
B) {
Y = 0.257 * R + 0.504 * G + 0.098 * B + 16;
U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
V = 0.439 * R - 0.368 * G - 0.071 * B + 128;
}
void RGBfromYUV(double& R, double& G, double& B, double Y, double U, double V)
{
Y -= 16;
U -= 128;
V -= 128;
R = 1.164 * Y + 1.596 * V;
G = 1.164 * Y - 0.392 * U - 0.813 * V;
B = 1.164 * Y + 2.017 * U;
}
49. 2.Color Space 49 / 14
색공간을 이용한 코드
RGB, YUV는 필수적으로 사용되는 건 알겠는데,
다른 색공간이 필요한 경우가 있을까?
앱에 기능 중 ColorPicker에서 색을 선택 후
수직이나 수평으로 드래그하면
명도와 채도를 변화하는 코드가 있다.
이를 RGB에서 구현하고자 하면 상당히 복잡하다.
가장 빠르고 단순하게 해결하는 방법은
다른 색공간을 이용하는 것이다.
앞에서 말했듯,
물론 색공간을 변화하면 일부 색이 손실되지만,
여기서는 큰 문제가 아니었기에
사용할 수 있는 방법이다.
50. 2.Color Space 50 / 14
색공간을 이용한 코드
HSV를 이용하면 쉽게 채도와 명도를 바꿀 수 있다.
이를 이용해 명도, 채도는 HSV공간안에서 변경 후에 최종 선택이 완료되면 다시 RGB로 변경해 최종 선택된
색을 넘기게 된다.
// 채도 ( width : Saturation : [1])
// 명도 ( height : bright : [2])
int red = Color.red(pixelColor);
int blue = Color.blue(pixelColor);
int green = Color.green(pixelColor);
if (mIsTouchDown) {
red = Color.red(mPreviousColor);
blue = Color.blue(mPreviousColor);
green = Color.green(mPreviousColor);
}
float[] colorHSV = new float[3];
Color.RGBToHSV(red, green, blue, colorHSV);
float saturation = (float) rawY / mHeightPixels;
float bright = (float) rawX / mWidthPixels;
colorHSV[1] = 2.0f * saturation;
colorHSV[2] = 2.0f - 2.0f * bright;
if (mOnColorPickedListener != null) {
mOnColorPickedListener.onColorPicked(Color.HSVToColor(colorHSV));
}
51. 3.Camera API
3. Camera API
51 / 14
Camera API 는 API level 21부터 deprecated 되었다.
하지만 앞서 말했듯 다양한 버전을 모두 서비스하는 환경에서
우리는 Camera API를 사용해야 한다.
52. 3.Camera API 52 / 14
Camera Class가 하는 일
1) Set image capture settings : 이미지를 가져오기 위한 설정을 함 ( LED Flash 키는 것도 포함 )
2) Start/Stop preview : 미리보기(preview)를 켜고 끔
3) Snap pictures : 실제 사진을 찍음
4) Retrieve frames for encoding for video : 비디오 녹화를 위해 동영상을 제공함
54. 3.Camera API 54 / 14
사진을 찍기 위한 단계
1. Obtain an instance of Camera from open(int).
: 카메라 인스턴스를 얻기 위해 open 메소드를 이용한다.
매개변수인 int는 카메라 id로 보통의 경우 전, 후면 카메라이다.
2. Get existing (default) settings with getParameters().
: getParameters() 메소드를 이용해 현재 카메라의 세팅을 가져온다.
3. If necessary, modify the returned Camera.Parameters object and call setParameters(Camera.Parameters).
: 카메라의 파라미터, 세팅을 변경이 필요하면 setParameters()를 이용해 세팅한다.
4. If desired, call setDisplayOrientation(int).
: 전달되는 영상의 출력 방향을 결정한다.
5. Important: Pass a fully initialized SurfaceHolder to setPreviewDisplay(SurfaceHolder).
Without a surface, the camera will be unable to start the preview.
: setPreviewDisplay를 통해 카메라 preview가 보여질 surfaceholder가 초기화 되어 전달되어야 한다. (뒤에 상세히 설명)
6. Important: Call startPreview() to start updating the preview surface.
Preview must be started before you can take a picture.
: startPreview()를 통해 preview를 시작하는데, 사진을 찍기전에 startPreview()는 무조건 실행되어야 한다.
55. 3.Camera API 55 / 14
사진을 찍기 위한 단계
7. When you want, call takePicture (Camera.ShutterCallback, Camera.PictureCallback)
to capture a photo. Wait for the callbacks to provide the actual image data.
: 사진을 찍을때 takePicture메소드를 실행하는데, Camera.PictureCallback을 통해 실제 이미지가 전달된다.
(실제 사용할일은 없다. 우리는 실제로 사진을 찍는 것이 아니라 Preview만을 이용하기 때문 )
8. After taking a picture, preview display will have stopped.
To take more photos, call startPreview() again first.
: 사진을 찍은 후에는 preview가 멈추기 때문에 다시 사진을 찍기 위해서는 startPreview()를 다시 실행해야만 한다.
( takePicture를 사용하지 않기에 발생하지 않는 단계 )
9. Call stopPreview() to stop updating the preview surface.
: stopPreview()는 실행하면 더 이상 preview를 갱신하지 않는다.
10. Important: Call release() to release the camera for use by other applications.
Applications should release the camera immediately
in onPause() (and re-open() it in onResume()).
: Camera 객체의 Life Cycle관리는 매우 중요하다.
Camera 객체는 시스템에서 하나밖에 사용하지 못하게 되어 있으므로,
앱의 Life Cycle에 맞춰서 release()를 해주지 않으면, 다른 앱에서 카메라를 사용할 수 없게 된다.
onPause()에서는 release()를 onResume()에서 open()을 하도록 작성해야 한다.
56. 3.Camera API 56 / 14
Android camera preview workflow
앞서 살펴본 단계를 생각해보면,
Camera 클래스의 open 메서드를 호출한다고 하면,
하드웨어 레벨까지 전달되고 다시 Application API 레벨까지 올라오는 것을 그릴 수 있어야 한다.
Android
Application
Android
Framework
Android
Runtime(JNI)
Client
Camera
Server
CameraService
Hardware
CameraHardwareStu
b
Open Camera
open native_setup connect connect HAL_openCameraHardWare
CameraHardWareStub instanceCamera instance
Binder(IPC)
57. 3.Camera API 57 / 14
Android camera preview workflow
다른 메서드 들도 같다고 생각하면 된다..
81. 4.Surface
4. Surface
81 / 14
Surface, SurfaceHolder, SurfaceView, GLSurfaceView, SurfaceTexture,
Surface Flinger, OpenGL, EGL…
Surface와 관련된 내용이 이것 저것 많이 나온다.
혼돈하지 말자. 의외로 간단하다.
Surface는 raw buffer이고,
SurfaceHolder는 말 그대로 Surface를 얻을 수 있게 해준다.
SurfaceView는 View계층 구조가 복잡해 빠른 반응속도가 필요한 게임, 동영상에서 쓰기 위해 만들어진 고속도
로(펀칭홀)라고 생각하자.
나머지는 이 후에 설명될 것이다.
84. 4.Surface 84 / 14
서피스 플링어 서비스
서피스 플링어 서비스는 여러 개의 Surface를 하나로 만들기 위해 서피스의
개념에 Z-order를 추가한 레이어개념으로 서피스를 관리
가장 큰 Z-order 값을 가장 먼저 그림
85. 4.Surface 85 / 14
EGL
서피스 플링어 서비스가 디스플레이 초기화 과정에서 EGL을 사용하고,
합성과정에서 OpenGL ES API를 사용. (OpenGL ES는 Embedded Systems의 약어로 임베디드에서 쓰이기 위한 OpenGL API
의 서브셋이다.)
뒤에 설명되는 OpenGL은 플랫폼에 독립적이다. 따라서 OpenGL의 명령에 따라 실제 각 디바이스에 그려줄 밑 부분이 필요한데,
그 역할을 EGL이 한다.
OpenGL ES
EGL
Native Window System
88. 4.Surface 88 / 14
SurfaceView란?
SurfaceView는 다른 View들과는 달리 직접 SurfaceView가 컨텐츠를 표시하지 않습니다.
일반적인 View는 화면에 뷰를 표시하는 연산과 기타 연산,
사용자와의 상호작용 처리 등이 모두 하나의 쓰레드에서 처리됩니다.
SurfaceView는 화면 업데이트를 백그라운드 쓰레드로 수행하여
어플리케이션의 자원을 잠식하지 않고 원활하게 뷰를 업데이트해줍니다.
SurfaceView는 OpenGL을 통한 가속이 지원되어 원활한 3D그래픽 표현도 가능합니다.
(GLSurfaceView)
109. 5.Texture 109 / 14
Texture는 같은 이미지 포맷의 이미지를 한 개 혹은 그 이상을 포함하는 OpenGL 오브젝
트이다.
110. 5.Texture 110 / 14
Texture 사용예
귤을 예를 들어 실제 처럼 보이게 하기 위해
1. 색상을 추가하고
2. 빛을 추가 한 후에
3. 실제 귤의 이미지를 입히면
더욱 귤 같이 보일 것이다.
이때 귤의 이미지를 Texture라고 하고 실제 Object에 입히는 것을 mapping이라고 한다.
116. 6.OpenGL
6. OpenGL
116 / 14
정리된 글 출처
OpenGL은 게임에서 이용하는 것이라고 생각할 수 있다.
하지만 카메라 앱을 만들기 위해서 OpenGL은 필수이다.
안드로이드에서 Native 프로그래밍을 하지 않고 GPU를 이용하기 위해서는 OpenGL을 이용하거나
Renderscript를 이용하는 방법 밖에 없기 때문이다.
자세한 내용은 이 곳을 참고하면 된다.
http://soen.kr/lecture/library/opengl/opengl-1.htm
117. 4.Surface 117 / 14
OpenGL 특징
OpenGL의 특징은 이름에 포함된 Open이라는 단어에서 대부분 유추할 수 있다.
개방되어 있고 무료이며 이식성이 뛰어나다.
① 그래픽 라이브러리는 구체성을 기준으로 고수준과 저수준으로 분류되는데 OpenGL은 저수준 라이브러리이다.
VRML같은 고수준 라이브러리는 물체간의 관계를 정의함으로써 장면을 그려낸다.
이에 비해 저수준 라이브러리는 모델링보다는 랜더링 기능이 주이며 세부적인 명령을 일일이 전달함으로써 물체의 가장 기본적인
요소를 그린다.
사용 방법이 훨씬 더 어렵지만 세세한 부분까지 그릴 수 있다.
② 개방된 표준이므로 플랫폼에 독립적이다.
운영체제와 연관된 부분이 없고 디바이스 드라이버를 통해 하드웨어를 직접 제어하므로 드라이버만 존재하면 모든 하드웨어 환경
에서 실행할 수 있다.
대부분의 데스크탑 환경, 모바일 환경은 물론이고 PlayStation, Nintendo 등의 게임기 등에도 광범위하게 이식되어 있다.
118. 4.Surface 118 / 14
OpenGL 특징
③ 간단한 함수들로 구성되어 있으므로 개발 언어에도 독립적이다.
C/C++, C#, 자바, 파이썬 등 대부분의 언어에서 사용 가능하다.
함수 기반이므로 C 언어가 가장 적합하되 객체 지향의 이점까지 고려하면 C++이 가장 유리하다.
무엇보다 문서와 예제가 풍부하고 재사용한 코드를 쉽게 구할 수 있다는 것이 큰 이점이다.
또 그래픽 프로그램이 요구하는 속도를 충분히 만족한다.
④ 하드웨어의 가속 기능을 최대한 활용하여 효율적으로 동작한다.
하드웨어가 지원하지 않는 기능은 소프트웨어로 흉내낼 수도 있으므로 느려지거나 품질이 나빠지더라도 최소한 그려내기는 한다.
119. 4.Surface 119 / 14
OpenGL 특징
OpenGL 함수들은 일반 함수와 구분하기 위해 예외없이 접두어가 붙는다.
gl 라이브러리의 함수는 gl 접두어로 시작하고 glu의 라이브러리는 glu로 시작한다.
마찬가지로 glut 소속의 함수는 glut 접두가 붙는다.
접두어만으로도 OpenGL 함수임을 쉽게 알 수 있다.
OpenGL은 C 수준의 함수들로 구성되어 있으므로 객체 지향과는 거리가 멀다.
그래서 함수 오버로딩(Overloading)을 지원하지 않으며 인수의 개수와 타입이 다른 동명 함수를 작성할 수 없다.
동일한 동작을 하되 인수 목록이 다르면 함수의 이름도 매번 달라져야 한다.
120. 4.Surface 120 / 14
OpenGL 특징
그래픽 출력에는 좌표뿐만 아니라 아주 많은 요소들이 개입된다.
색상, 굵기, 모양, 조명, 각종 모드 등등 여러 가지 정보들이 필요하다.
그리기 함수들은 도형 출력을 위해 이 모든 정보들을 참조하지만 그렇다고 해서 이 정보들을 모두 함수의 인수로 전달할 수는 없다.
그렇게 하다가는 인수 목록이 한없이 길어질 것이며 잘 바뀌지도 않는 값을 매번 전달하는 것도 낭비이다.
그래서 OpenGL은 그리기에 필요한 여러 가지 정보들을 상태 머신(State Machine)에 저장한다.
상태 머신이란 상태를 저장하는 장소이며 그리기에 영향을 미치는 여러 변수값들이 집합이다.
배경 색상은 GL_COLOR_CLEAR_VALUE 상태 변수에 저장되며 현재 정점의 색상은 GL_CURRENT_COLOR 상태 변수에 저장된
다
121. 7.Case Study
7. Case Study
121 / 14
총정리
지금까지 배운 기술을 바탕으로 실제 카메라의 Preview로 넘어온 영상을 동영상으로 저장하는 프로세스를 경험
해 보자.
실제코드는 https://github.com/google/grafika 를 참고하기 바란다.
123. 4.Surface 123 / 14
Camera Preview
Renderer
onSurfaceCreated
1) GL_TEXTURE_EXTERNAL_OES영역에 Texture 생성
GLES20.glGenTextures
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES
2) 해당 Texture로 SurfaceTexture 생성
mSurfaceTexture = new SurfaceTexture(textureId)
3) vertexShader, fragmentShader 정의
4) 생성된 SurfaceTexture의 OnFrameAvailableListener 지정
SurfaceTexture에 새로운 이미지프레임이 왔을 때 불리는 callback
mSurfaceTexture.setOnFrameAvailableListener(this);
5) 생성된 SurfaceTexture 로 setPreviewTexture
camera.setPreviewTexture(surfaceTexture);
6) 카메라 preview 시작
camera.startPreview();
124. 4.Surface 124 / 14
Camera Preview
Renderer
onFrameAvailable
1) SurfaceTexture는 새로운 프레임이 있다는 신호를 받는
용도로 사용되고, requestRender는 어느 쓰레드에서도
호출 할 수 있다.
이 결과로 Renderer의 onDrawFrame이 실행됨.
glSurfaceView.requestRender();
125. 4.Surface 125 / 14
Camera Preview
Renderer
onDrawFrame
1) updateTexImage()를 실행하여, 이미지 스트림으로부터 가장
최신의 프레임으로 texture 이미지를 업데이트한다.
만약 최신 프레임이 없으면 기존 이미지를 재사용함.
mSurfaceTexture.updateTexImage();
2) TransformMatrix에서 사용할 Matrix 지정.
TransformMatrix는 기본 좌표계의 버텍스가 이 행렬에 곱해져서
새로운 좌표계로 변환된 버텍스를 얻기 위해 사용되는 행렬
( 회전, 이동, 크키 )
updateTexImage()를 사용할때 마다 사용할 Matrix가 달라질 수
있으므로 매번 새롭게 지정해줘야 함.
mSurfaceTexture.getTransformMatrix(mSTMatrix);
126. 4.Surface 126 / 14
Camera Preview
Renderer
onDrawFrame
3) OpenGL vertex shader, fragment shader 실행
4) 렌더링 실행
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
5) GL 명령어 실행
GLES20.glFlush();
127. 4.Surface 127 / 14
Camera Preview
GLSurfaceView
Renderer
Camera
2) GL_TEXTURE_EXTERNAL_OES영역에 Texture 생성
해당 Texture로 SurfaceTexture 생성
SurfaceTexture
3) setPreviewTexture
(surfaceTexture);
4) preview 갱신
5) onFrameAvailable
- requestRenderer(); 호출
6) onDrawFrame
SurfaceTexture.updateTexImage();
7) GL rendering
1) setRenderer
8) eglSwapBuffers
mEgl.eglSwapBuffers(mEglDisplay,
mEglSurface);
145. 4.Surface 145 / 14
Camera Preview
GLSurfaceView
eglSwapBuffers
- 현재 버퍼를 전송, 이 함수의 이름은 전면 버퍼와 후면 버퍼를
교체했던 전통 방식에서 유래됐으나, 실제 구현은 이제 다를 수
있다.
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
150. 4.Surface 150 / 14
Camera Preview
dequeueBuffer
FramebufferNativeWindow에게 다음에 그릴 buffer요청
151. 4.Surface 151 / 14
Camera Recording
Renderer
Encoder
1. 현재 사용중인 EGLContext 넘김
EGL14.eglGetCurrentContext()
2. TextureID 넘김
1. prepareEncoder
2. OpenGL draw
3. EGL works
4. drainEncoder
5. End of stream
152. 4.Surface 152 / 14
Camera Recording
Encoder
prepareEncoder #1
1) MediaCodec 설정
2) MediaCodec에서 사용할 surface 생성
3) MediaMuxer 설정
4) EGLContext 생성 (eglCreateContext)
5) EGLSurface 생성 (eglCreateWindowSurface)
6) OpenGL vertex shader, fragment shader
154. 4.Surface 154 / 14
Camera Recording
Encoder
prepareEncoder #3
1) 버퍼 메타데이터 정보 생성 (코덱의 출력버퍼와 관련된 내용)
mVideoBufferInfo = new MediaCodec.BufferInfo();
2) 인코딩에 사용될 미디어포맷 생성
- String/Value 쌍으로 구성된 미디어 데이터 정보
MediaFormat videoFormat =
MediaFormat.createVideoFormat(
VIDEO_MIME_TYPE, width, height);
public static final MediaFormat createVideoFormat(String mime, int width, int height) {
MediaFormat format = new MediaFormat();
format.setString(KEY_MIME, mime);
format.setInteger(KEY_WIDTH, width);
format.setInteger(KEY_HEIGHT, height);
return format;
}
155. 4.Surface 155 / 14
Camera Recording
Encoder
prepareEncoder #4
2) 인코딩에 사용될 미디어포맷 생성
- String/Value 쌍으로 구성된 미디어 데이터 정보
MediaFormat.KEY_COLOR_FORMAT
사용할 색공간을 지정함.
COLOR_FormatSurface은 GraphicBuffer의 메타데이터 리퍼런스
videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
156. 4.Surface 156 / 14
Camera Recording
Encoder
prepareEncoder #5
3) 미디어 인코더 생성, 설정
mVideoEncoder =
MediaCodec.createEncoderByType(VIDEO_MIME_TYPE);
mVideoEncoder.configure(videoFormat, null, null,
MediaCodec.CONFIGURE_FLAG_ENCODE);
4) Encoder가 사용할 surface 생성
mInputSurface = mVideoEncoder.createInputSurface();
157. 4.Surface 157 / 14
Camera Recording
Encoder
prepareEncoder #6
5) 인코더 시작
mVideoEncoder.start();
6) Muxer 생성
mMuxer = new MediaMuxer(outputFile.toString(),
MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);