본문 바로가기

dev/flutter

flutter google cloud Vision API (OCR)

이미지에서 텍스트를 추출할 수 있는 기능을 구현해보았다.

이를 위한 방법으로는 3가지 정도로 나눌 수 있다.

 

 

1. google_ml_kit 라이브러리

플러터를 사용한다면 간단히 AI 기능을 사용할 수 있다.

 

 

google_ml_kit | Flutter package

A Flutter plugin to use all APIs from Google's standalone ML Kit for mobile platforms.

pub.dev

 

 

2. 파이어베이스 ML kit

온디바이스 AI기술을 구현하기 위해서 좋은 방법인 것 같다.

 

 

Android에서 ML Kit를 사용한 이미지 속 텍스트 인식  |  ML Kit for Firebase

Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 Android에서 ML Kit를 사용한 이미지 속 텍스트 인식 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를

firebase.google.com

 

 

3. 구글 클라우드 Vision API

API를 통해 쉽게 AI기술을 이용할 수 있다. 자바, 노드 등 다양한 곳에서 사용할 수 있다.

 

 

이미지의 텍스트 감지  |  Cloud Vision API  |  Google Cloud

의견 보내기 이미지의 텍스트 감지 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 스캔된 문서에서 텍스트를 감지하는 경우 광학 문자 인식, 구조화된 양식

cloud.google.com

 

 

위의 3가지 모두 텍스트 감지뿐만 아니라 다양한 AI 기술을 사용할 수 있다.

여기서 구글 클라우드의 Vision API를 사용해 보았다.

 

 

1. google cloud 프로젝트를 생성한다.

 

2. IAM 주체를 생성한다.

해당 프로젝트의 여러 사용자에 대한 권한을 정의할 수 있다.

 

 

 

 

3. 서비스 계정 탭에서 서비스 계정을 만들고 키를 발급 받는다.

서비스 계정을 만들면 IAM 탭에 자동으로 등록이 된다.

키는 json 파일로 다운로드 하고 적당한 경로에 위치시킨다.

 

 

 

4. 결제 계정을 생성하거나 해당 프로젝트와 연동시킨다.

결제 계정을 등록하지 않으면 404-'BILLING_DISABLED'가 응답된다..

결제 계정 관련은 프로젝트 개요페이지 에서 결제 탭으로 이동하면 된다.

* 한달에 1000개 까지는 무료라고 한다.

 

 

5. gloud CLI를 설치 한다.

해당 페이지에 나온대로 따라하면 된다.

 

1) google-cloud-sdk 다운로드

 

 

gcloud CLI 설치  |  Google Cloud CLI 문서

의견 보내기 gcloud CLI 설치 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 페이지에는 Google Cloud CLI 설치를 선택하고 유지하기 위한 안내가 포함되어 있습

cloud.google.com

 

2) 적당한 경로에 압축을 풀고 sdk 설치

 

{압축해제 한 경로}/google-cloud-sdk/install.sh
# 설치 완료 후 터미널을 다시 열고
gcloud init
# 'y' 버튼을 누르면서 설치를 진행한다.

 

3) 구글 계정으로 로그인하라는 메시지가 뜨면 프로젝트를 생성한 아이디로 로그인해준다.

 

4) 해당 계정이 가진 구글 클라우드 프로젝트 중 활성화할 프로젝트를 선택한다.

 

 

 

6. gloud 를 통해 vision API를 사용하기 위한 엑세스 토큰을 얻는다

 

# 터미널에 아래 명령어 입력
gcloud auth activate-service-account —key-file={json 파일 위치/keyfile.json}
# Activated service account credentials for: [활성화된 서비스계정명] 
# 위와 같은 말이 나오면 완료된 것이다. 아래 명령어로 토큰을 얻는다.
gcloud auth print-access-token

 

 

7. 플러터에서 api 요청 코드 작성

http, image_picker 라이브러리 사용

 

class _MyHomePageState extends State<MyHomePage> {

  XFile? image;
  String result = "";


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
        
              if (image != null)
              Image.file(File(image!.path)),
        
              ElevatedButton(
                onPressed: () async {
                  final ImagePicker picker = ImagePicker();
            
                  // 이미지 1개 불러오기
                  final XFile? image = await picker.pickImage(source: ImageSource.gallery);
                  if (image != null) {
                    this.image = image;
                  }
        
                  setState(() {
                  });
                },
                child: Text('get image')
              ),
        
              if (result.isNotEmpty)
              Text(result, textAlign: TextAlign.center),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          log("image: ${image!.path}");
          await textDetection(imagePath: image!.path);
        },
      ),
    );
  }

  /// 이미지 base64인코딩
  Future<String> encodeImageToBase64(String imagePath) async {
    final imageFile = File(imagePath);
    final Uint8List imageBytes = await imageFile.readAsBytes();
    return base64Encode(imageBytes);
  }

  /// 텍스트 추출
  Future<void> textDetection({
    required String imagePath
  }) async {
	// 이미지 인코딩
    String base64Image = await encodeImageToBase64(imagePath);
	
    // 요청 본문
    final request = {
      "requests": [
        {
          "image": {
            "content": base64Image
          },
          "features": [
            {
              "type": "TEXT_DETECTION"
            }
          ]
        }
      ]
    };
    
    // 헤더
    final headers = {
      'Authorization': "Bearer ${토큰}",
      'x-goog-user-project': ${프로젝트 ID},
      'Content-Type': "application/json; charset=utf-8",
    };
    
    // api 요청
    try {
      final http.Response response = await http.post(
        Uri.parse('https://vision.googleapis.com/v1/images:annotate'),
        headers: headers,
        body: jsonEncode(request),
      );

      if (response.statusCode == 200) {
        // log("response: ${response.body}");
        setState(() {
          // 추출한 텍스트 데이터 꺼내기
          result = jsonDecode(response.body)['responses'][0]['textAnnotations'][0]['description'];
          log("result: $result");
        });
      }

    } catch (err) {
      log("http error : $err");
    }


  }
}

 

 

API 요청 문서를 보면 어떻게 보내야하는지 잘 나와있다.

중요한 건 이미지를 base64문자열로 인코딩해야 하고, 헤더값에 토큰과 해당 프로젝트 ID가 필요하다.

또, 요청 본문을 json으로 보내야 한다.

 

여러 각도로 이미지를 찍어봤는데, 생각보다 잘 추출하는 것 같다.

추출된 텍스트의 위치도 나오므로 이 데이터를 이용할 수도 있을 듯 하다.

 

* 추출한 토큰은 1시간? 정도의 유효기간이 있는 듯 하다. 401이 뜨면 토큰을 재발행해야 한다.

 

* 프로젝트 ID보는 방법

구글 클라우드에서 프로젝트 선택 버튼을 누르면 나오는 리스트중 우측의 ID값을 넣으면 된다.

 

'dev > flutter' 카테고리의 다른 글

flutter 애플 로그인  (0) 2024.05.18
flutter 구글 로그인  (1) 2024.03.18
[빌드 에러] libobjc.A.dylib is being read from process memory.  (0) 2024.01.17
flutter 네이버 지도  (0) 2023.11.14
flutter 커스텀 앨범  (0) 2023.11.08