본문 바로가기

Develop

음식 이미지 분석 flutter 앱 개발

1. 오늘의 변경 사항: Firebase 연동 및 이미지 분석 워크플로우 개선

어제 하루 동안 Firebase 연동을 포함해 이미지 분석 기능, UI, 그리고 코드 구조를 전반적으로 개선했습니다. 이번 변경 사항의 핵심은 Firebase Storage를 활용한 이미지 업로드, 이미지 분석 진행 상황 UI 추가, 코드 리팩터링 그리고 동적 링크(Share 기능) 지원입니다.


2. 소개

이번 개선 사항으로 인해 앱에서 사진을 찍고 서버로 전송해 AI 분석을 진행하는 과정이 훨씬 간편해졌습니다. 또한, Firebase와 연동하여 분석 이미지 및 데이터를 안전하게 저장하고 공유할 수 있습니다. 블로그 글을 통해 새롭게 추가된 기능 및 코드 변경 내용을 살펴보세요!


3. 변경 사항 설명

3-1. .gitignore 파일 업데이트

  • 추가: /firebase.json
    - Firebase 설정 파일을 버전에 따라 관리할 수 있도록 .gitignore에서 제외 대상에서 일부를 조정했습니다.

주요 포인트

  • Firebase 관련 설정 파일을 소스 제어에서 어떻게 다룰지 결정해야 합니다.
  • .gitignore 변경 시 팀 전체에 영향을 미치므로 주의가 필요합니다.

3-2. AndroidManifest.xml 권한 선언 및 딥 링크 설정

  • 권한 추가: INTERNET, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE
    - 이미지 파일을 로컬 디스크에 저장하고 Firebase에 업로드하기 위해 필요합니다.
  • 딥 링크(Intent-filter) 추가:
    - android:host="meallens.page.link"과 android:scheme="https" 설정을 통해 페이지 링크(Dynamic Links) 기능을 구현할 준비를 했습니다.

주요 포인트

  • 사용자 휴대폰 내부 저장소 접근을 위해 권한을 정확하게 관리해야 합니다.
  • Dynamic Links를 통해 앱 외부 공유 링크가 앱 내부로 연결되도록 설정할 수 있습니다.

3-3. android/settings.gradle: FlutterFire 플러그인 추가

// START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false
// END: FlutterFire Configuration
  • Firebase를 사용하기 위해 com.google.gms.google-services 플러그인을 적용할 수 있도록 준비했습니다.

주요 포인트

  • Firebase 기능(Analytics, Storage 등)을 제대로 동작시키기 위해 필수적인 플러그인 설정입니다.

3-4. meal_controller.dart 리팩터링 및 이미지 분석 기능 개선

  1. Progress Callback 도입
    • AnalysisProgress 클래스를 만들어 분석 진행 상황을 UI에 표시하도록 했습니다.
    • analysisProgress라는 Rx<AnalysisProgress?> 상태 변수를 추가했습니다.
  2. 이미지 업로드 로직 분리
    • 기존에는 FlutterImageCompress를 이용해 압축 후 직접 업로드했지만, 이제 ImageService를 사용하여 이미지 최적화 및 저장 과정을 한 곳에서 관리합니다.
  3. 에러 처리를 간소화
    • debugPrint 대신 print로 전환하거나 rethrow로 에러를 한꺼번에 처리하도록 변경했습니다.

요약

  • 분석 진행 상태를 UI로 피드백받을 수 있게 하여 사용자 경험을 높임
  • 이미지 처리 로직을 ImageService로 분리해 코드 가독성과 재사용성을 높임
  • 오류 처리 로직을 일관성 있게 정비

3-5. dynamic_links_service.dart(신규 파일)

  • 공유하기(Share) 기능 구현
    • 화면을 캡처해 이미지로 저장한 뒤 다른 앱에 공유할 수 있도록 share_plus 패키지를 사용했습니다.
    • GlobalKey와 RenderRepaintBoundary를 이용해 위젯을 스크린샷 찍어 공유하도록 구현했습니다.

주요 포인트

  • share_plus 라이브러리를 사용해 손쉽게 이미지와 텍스트를 다른 앱으로 공유
  • 향후 딥 링크나 URL 스킴 기반으로 공유 범위를 확장 가능

3-6. image_service.dart(신규 파일)

  1. 이미지 최적화
    • package:image를 이용해 최대 크기(1920px)를 제한하고, JPEG 품질(85%)로 조정하여 이미지 용량을 줄였습니다.
  2. 캐시 정리
    • 7일 이상된 임시 파일(optimized_*)을 자동 삭제해 디스크 용량을 절약합니다.
  3. Firebase Storage 연동 대비
    • 우선은 앱 문서 디렉토리에 저장하도록 했지만, 추후 Firebase Storage 업로드 로직을 추가할 여지를 마련해 두었습니다.

주요 포인트

  • 크기 제한 및 품질 조정으로 네트워크 및 저장소 최적화
  • 오래된 캐시 삭제로 디바이스 저장 공간 절약

3-7. openai_service.dart AI 분석 진행 상황 표시

  • ProgressCallback: 이미지 인코딩, AI 호출, 응답 처리 단계를 세부적으로 나누어 UI에 진행 상황을 알림
  • 오류 처리: AI 응답을 파싱할 때 예외 상황을 좀 더 명확히 처리하고 로그를 남기도록 했습니다.

주요 포인트

  • 비동기 작업 시 진행 상태를 알려줘 사용자 피로도 감소
  • AI 응답 파싱 오류를 알기 쉽게 디버깅할 수 있도록 개선

3-8. UI 변경 사항

3-8-1. home_screen.dart

  • 분석 진행 상태 Dialog(AnalysisProgressDialog)를 오버레이로 띄워 사용자에게 진행 상황을 실시간으로 노출합니다.
  • FAB 버튼에 마우스 호버 애니메이션을 추가하여 UX를 강화했습니다.
  • 식사 리스트가 없는 경우, 안내 문구와 간단한 그래픽으로 빈 화면을 표현해 사용자에게 “첫 식사를 등록하라”고 유도합니다.

3-8-2. meal_detail_screen.dart

  • 공유 버튼 추가(오른쪽 상단), shareScreenshot 메서드를 통해 캡처 후 공유
  • 상세 화면에서 영양 정보, 추천 사항 등을 카드 형태로 보기 좋게 배치
  • 삭제 다이얼로그 문구를 조금 더 친절하게 변경

3-8-3. analysis_progress_dialog.dart(신규 파일)

  • CircularProgressIndicator와 함께 **진행률(%)**을 표시하고, 메시지를 실시간으로 갱신해줍니다.

요약

  • 사용자 경험(UX) 개선: AI 분석 중인 상황을 명확히 안내
  • 공유 기능 추가: 앱 외부에도 손쉽게 분석 결과를 공유할 수 있음

3-9. firebase_options.dart 변경

  • Firebase 초기화 시 사용될 API 키프로젝트 ID, 앱 ID 등을 정의했습니다.
  • 실제 배포 시에는 이 정보를 안전하게 관리해야 합니다(.env나 CI/CD 비밀 변수 활용).

주요 포인트

  • 배포 환경에 따라 Firebase 설정값이 달라질 수 있으므로 주의
  • API 키 보안 유의 (서버 보안 규칙과 함께 사용 권장)

3-10. main.dart 초기화 로직 수정

await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);
  • DefaultFirebaseOptions를 통해 각 플랫폼별 Firebase 설정을 불러옵니다.
  • .env 파일 로딩 실패 시 에러를 출력하도록 로직 보강.

주요 포인트

  • Firebase를 초기화하지 않으면 앱 실행 시 에러가 발생할 수 있으므로 필수 단계
  • dotenv로 환경 변수를 로드해 Key를 안전하게 관리

3-11. pubspec.yaml 의존성 추가

firebase_storage: ^11.5.6
share_plus: ^7.2.1
path_provider: ^2.1.1
cached_network_image: ^3.3.1
permission_handler: ^11.1.0
image: ^4.1.3
path: any
  • Firebase Storage공유 라이브러리이미지 처리에 필요한 의존성을 추가했습니다.
  • path, permission_handler, cached_network_image 등 다양한 패키지를 활용할 수 있는 기반을 마련했습니다.

주요 포인트

  • 최신 버전을 사용하려면 Gradle, Kotlin, Dart 버전 호환성도 체크 필요
  • iOS, Android 동시 빌드 시 주의(특정 버전 충돌 가능성)

3-12. storage.rules 파일 추가

rules_version = '2';
service firebase.storage {
  ...
}
  • Firebase Storage 보안 규칙을 설정하여 인증된 사용자만 쓰기 가능하도록 설정했습니다.
  • 공개 읽기(allow read)는 테스트용이므로 프로덕션에서 필요에 따라 변경을 고려해야 합니다.

주요 포인트

  • 보안 규칙은 무조건 배포 전 다시 확인해야 합니다.
  • 앱에서 정상적으로 업로드/다운로드가 가능한지 테스트해야 합니다.

4. 결론

  • Firebase 연동으로 이미지를 안전하게 저장하고 공유하기 쉬워졌습니다.
  • 이미지 분석 진행 상황을 실시간으로 알 수 있어 사용자 경험이 크게 개선되었습니다.
  • 코드 리팩터링을 통해 각 기능을 모듈 단위로 분리하여 가독성과 유지 보수성을 높였습니다.

https://play.google.com/store/apps/details?id=com.hoodpub.meal_lens

 

식사진 - Google Play 앱

식사진은 AI 기술을 활용하여 음식 사진을 분석하는 앱입니다.

play.google.com

 

 

앞으로도 더 나은 기능과 개선점을 꾸준히 블로그에 기록할 예정이니, 많은 관심 부탁드립니다! 감사합니다.