728x90
증강현실기술을 끌어와서 가상 메이크업을 한 모습을 실시간으로 확인할 수 있는 걸 구현하려고 했다.
ui만들고 안드로이드 코드짜고, service에서 플러터 코드도 짜서 플랫폼 채널로 안드로이드 신호가 오는걸 확인했다.
카메라도 연동하고 켜서 얼굴 감지도 시켰다.
하지만 아쉽게도 잘 되지는 않았다.
이유가 안드로이드 코드를 몰라서 초기화 문제가 발생했다.
얼굴 감지를 하고 초기화하고 다시 프레임별로 얼굴 감지를 하게 되어서, 어느순간은 얼굴감지가 되다가 어느순간은 되지 않았다.
한번 초기화 할때 다시 시작이 안되도록 되었고 초기화 코드를 수정해야하는데, 코틀린에서 문제인지 플러터에서 문제인지 모르겠고, 초기화 해야하는곳을 지티피도 모르고 나도 몰라서 계속 물어보다가 나온결론이
내가 코틀린 언어를 보고 초기화 부분과 플러터의 초기화 부분을 비교해서 그 부분을 계속 감지하도록 수정해줘야했다.
결국 코틀린 언어를 몰라서 멈추게 되었다. 나중에 코틀린 공부해서 그 부분을 찾아서 구현시켜봐야 겠다.
AR 메이크업 앱 개발 과정
1단계: 기본 설정 ✅
- AndroidManifest.xml 설정
<manifest>
<!-- AR 필수 권한 설정 -->
<uses-permission android:name="android.permission.CAMERA"/>
<!-- AR 기능 명시 -->
<uses-feature android:name="android.hardware.camera.ar" android:required="true"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<application>
<!-- ARCore 설정 -->
<meta-data android:name="com.google.ar.core" android:value="required" />
<meta-data
android:name="com.google.android.ar.API_KEY"
android:value="발급받은_API_키"/>
</application>
</manifest>
build.gradle 설정
defaultConfig {
minSdk = 24 // ARCore 요구사항
}
dependencies {
implementation 'com.google.ar:core:1.36.0'
}
2단계: Platform Channel 구현 ✅
- Flutter 측 (ar_service.dart)
class ArService {
static const platform = MethodChannel('com.example.onlyveyou/ar');
Future<bool> startAR() async {
try {
final bool result = await platform.invokeMethod('startAR');
return result;
} on PlatformException catch (e) {
print('Error starting AR: ${e.message}');
return false;
}
}
Future<bool> initializePreview(int textureId) async {
try {
final bool result = await platform.invokeMethod('initializePreview', {
'textureId': textureId,
});
return result;
} on PlatformException catch (e) {
print('Error initializing preview: ${e.message}');
return false;
}
}
// 필터 적용, 이미지 캡처 등 추가 메서드...
}
Android 측 연결 (MainActivity.kt)
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.example.onlyveyou/ar"
private lateinit var arHandler: ArHandler
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
arHandler = ArHandler(
context = this,
activity = this,
flutterTextureRegistry = flutterEngine.renderer
)
MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
CHANNEL
).setMethodCallHandler { call, result ->
try {
arHandler.onMethodCall(call, result)
} catch (e: Exception) {
result.error("HANDLER_ERROR", e.message, null)
}
}
}
}
AR 처리 핸들러 (ArHandler.kt)
class ArHandler(
private val context: Context,
private val activity: Activity,
private val flutterTextureRegistry: TextureRegistry
) : MethodCallHandler {
private var arSession: Session? = null
private var cameraPreview: ArCameraPreview? = null
private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null
override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"startAR" -> handleStartAR(result)
"initializePreview" -> handleInitializePreview(result)
// 추가 메서드 처리...
}
}
private fun handleStartAR(result: Result) {
try {
if (ArCoreApk.getInstance().checkAvailability(context)
== ArCoreApk.Availability.SUPPORTED_INSTALLED) {
arSession = Session(context)
cameraPreview?.startCamera()
result.success(true)
} else {
result.error("AR_UNAVAILABLE",
"ARCore is not available on this device", null)
}
} catch (e: Exception) {
result.error("AR_ERROR",
"Error starting AR session: ${e.message}", null)
}
}
}
카메라 프리뷰 구현 (ArCameraPreview.kt)
class ArCameraPreview(private val context: Context) : TextureView.SurfaceTextureListener {
private var cameraManager: CameraManager =
context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
private var cameraDevice: CameraDevice? = null
private var surfaceTexture: SurfaceTexture? = null
fun setSurfaceTexture(texture: SurfaceTexture) {
surfaceTexture = texture
texture.setDefaultBufferSize(1080, 1920)
if (cameraDevice != null) {
createCameraPreviewSession()
} else {
startCamera()
}
}
fun startCamera() {
val cameraId = cameraManager.cameraIdList.find { id ->
cameraManager.getCameraCharacteristics(id).get(
CameraCharacteristics.LENS_FACING
) == CameraCharacteristics.LENS_FACING_FRONT
}
cameraId?.let {
cameraManager.openCamera(it, cameraStateCallback, backgroundHandler)
}
}
}
현재 진행 상황
- ✅ 기본 설정 완료
- ✅ Flutter-Native 통신 구현
- ✅ AR 세션 초기화
- 🔄 카메라 프리뷰 구현 중
- ⬜️ Face Detection 구현 예정
- ⬜️ 필터 오버레이 구현 예정
다음 단계
- 카메라 프리뷰 디버깅
- Face Detection 구현
- 필터 오버레이 시스템 구축
- AR 효과 구현
사용 기술
- Flutter & Dart
- Android Native (Kotlin)
- Google ARCore
- Platform Channel
- Camera2 API
728x90