-
📸 [Flutter] Google Cloud OCR 연동하기📖 개발 공부/flutter 2023. 10. 18. 22:48
나는 독서 기록을 할 때, 기억하고 싶은 구절은 기본 카메라앱으로 스캔 후 복사하여 노션에 붙여넣고 있다. 하지만 이 과정은 나에게 꽤나 번거롭다.
그래서 카메라에서 문장을 스캔&선택한 후 곧바로 해당 문장에 대한 나의 생각을 기록하고 싶어서 독서 기록 앱을 만들고 있다!
플러터로 개발을 하고 있고, 플러터로 Google Cloud OCR을 연동하여 이 기능을 구현해보려구 한다! 📸
코드 작성에 앞서, Google Cloud에서 제공하는 Vision AI 를 사용하기 위해 키를 발급 받아야 한다.
다음 링크에 들어가서 발급 받으면 된다.
발급받는 과정 요약
Vision AI 무료로 사용해보기 → 가입 → 서비스 계정 페이지로 이동 → “키” 탭에서 “키 추가” 선택 → 비공개 키 만들기 에서 키 유형 JSON으로 선택하여 만들기 선택다음은 curl 예시이다.
curl -X POST \\ -H "Authorization: Bearer $(gcloud auth print-access-token)" \\ -H "x-goog-user-project: PROJECT_ID" \\ -H "Content-Type: application/json; charset=utf-8" \\ -d @request.json \\ "<https://vision.googleapis.com/v1/images:annotate>"
요기에는 API 호출 방법이 정리되어있다!
💻 이제 플러터에 OCR을 연동해보자
나는 VisionApiService 클래스를 만들어서 호출하는 로직을 작성하였다.
코드블럭에 dart 언어도 지원해주세요..!import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:http/http.dart' as http; import 'package:flutter_dotenv/flutter_dotenv.dart'; class VisionApiService { final String baseUrl = dotenv.env['VISION_BASE_URL']!; final String projectId = dotenv.env['VISION_PROJECT_ID']!; final String gcloudToken = dotenv.env['VISION_AUTH_TOKEN']!; Future<String?> annotateImage(String imagePath) async { final request = VisionRequest( requests: [ AnnotateImageRequest( image: Image( content: await encodeImageToBase64(imagePath), ), features: [Feature()], ), ], ); final headers = { HttpHeaders.authorizationHeader: "Bearer $gcloudToken", "x-goog-user-project": projectId, HttpHeaders.contentTypeHeader: "application/json; charset=utf-8", }; final response = await http.post( Uri.parse(baseUrl), headers: headers, body: jsonEncode(request.toJson()), ); if (response.statusCode == 200) { Map<String, dynamic> jsonResponse = json.decode(response.body); // "responses" 배열에서 첫 번째 항목의 "textAnnotations" 배열 가져오기 List<dynamic> textAnnotations = jsonResponse['responses'][0]['textAnnotations']; if (textAnnotations.isNotEmpty) { // "description" 필드 추출 String description = textAnnotations[0]['description']; return description; } } return null; } } Future<String> encodeImageToBase64(String imagePath) async { final imageFile = File(imagePath); final Uint8List imageBytes = await imageFile.readAsBytes(); return base64Encode(imageBytes); } class VisionRequest { final List<AnnotateImageRequest> requests; VisionRequest({required this.requests}); Map<String, dynamic> toJson() => { 'requests': requests.map((request) => request.toJson()).toList(), }; } class AnnotateImageRequest { final Image image; final List<Feature> features; AnnotateImageRequest({required this.image, required this.features}); Map<String, dynamic> toJson() => { 'image': image.toJson(), 'features': features.map((feature) => feature.toJson()).toList(), }; } class Image { final String content; Image({required this.content}); Map<String, dynamic> toJson() => { 'content': content, }; } class Feature { final String type = "TEXT_DETECTION"; Map<String, dynamic> toJson() => { 'type': type, }; }
dotenv 패키지가 궁금하다면?
이 서비스에선 텍스트 인식만 하는 기능만 필요로 하므로 type을 TEXT_DETECTION 로 한정하였다.
Google Cloud OCR을 사용하고 싶은 분들은 위 코드를 참고하시길! 😉
visionApi 호출이 잘되는지 확인하기 위해 테스트해본 코드를 일부 가져와보았다.
Button( text: "텍스트 인식 테스트 버튼", fontColor: Colors.white, fontSize: 20, buttonWidth: 240, buttonHeight: 50, onTap: () async { var image = await ImagePicker() .pickImage(source: ImageSource.gallery); if (image != null) { final text = await visionApiService.annotateImage(image.path); textEditingController = TextEditingController(text: text); } }, ),
갤러리에서 이미지를 선택하면 visionApi를 호출하여 TextField 안에 채워진다.
코드만 보면 삼삼하니 화면으로 플로우를 캡쳐해보았다!
아직 개발 중이라 기능 더 고도화를 해보겠지만! OCR 도입은 요로코롬 하면 된다~
반응형'📖 개발 공부 > flutter' 카테고리의 다른 글
[Flutter] .env 파일 이용하여 환경변수 관리하기 (0) 2023.10.02 [Flutter] Flutter는 어떻게 동작하는가? (0) 2023.08.05 [Flutter] App Lifecycle (라이프사이클) (0) 2023.07.23 [Flutter] Stateless Widget / Stateful Widget (0) 2023.07.22 [Flutter] Line Chart 구현하기 (0) 2023.05.07