GAS

Vision APIでサムネイル画像からテキスト抽出するGASスクリプト

thumbnail
n-mukineer
えぬ
えぬ

こんにちは、えぬ(@nmukineer)です!

今回は、Google Cloud の Vision APIを使って、ブログのサムネイル画像からテキストを抽出するGASスクリプトを書いてみました。

Vision APIでテキストを抽出するまでの流れ

Vision API(Google Cloud Vision API)とは?

Vision AIとVision APIの関係性

えぬ
えぬ

Vision AIとVision APIがあってややこしい…

Vision APIを利用するにあたり、サービスの立ち位置を整理しておきましょう。

Vision AIとVision APIは、こちらの図のような関係性となっています。

Vision APIはVision AIの中の一つのAPIサービス

つまり、Vision AIという括りの中に、1つのサービスとしてVision APIが提供されているという構造となっています。

Vision APIって何?

Vision APIは、Googleが提供する画像解析のためのAPIサービスです。

画像から顔や企業ロゴを検出したり、画像から特徴的な建造物を抽出するなど、さまざまな機能があるようです。

今回はその中でも、TEXT_DETECTIONという、画像からテキストを抽出するAPI(光学式文字認識:OCR)を使ってみました。

Vision APIの料金

Vision APIは、最初の1,000ユニット(1カ月あたり)は無料となっています。さらに、最初は300ドル分の無料クレジット(90日間有効)をもらえるので、相当ヘビーユースしない限りは課金の対象にならないかと思います!

Cloud Vision APIの料金体系(2022年12月現在)
  • 最初の1,000ユニット/月:無料
  • 1,001~5,000,000ユニット/月:$1.50(1,000ユニットあたり)
  • 5,000,001以上のユニット/月:$1.00(1,000ユニットあたり)
  • 最新情報は、公式ページよりご確認ください

Vision APIを使えるようにする手順

Vision AIを使えるようにすることで、その子サービスであるVision APIを利用することが可能になります。利用開始までの操作は以下の手順で行います。

Vision AIページにアクセスし「Vision AIを無料で試す」をクリック
アカウント情報の入力(1/2)

国籍、利用目的、利用規約へのチェックを入れ、「続行」をクリックします。

アカウント情報の入力(2/2)

クレジットカード情報を入力し、「無料トライアルを開始」をクリックします。

アンケートに答える(スキップ可)

4つのアンケートに答えるポップアップが出ますので回答します。(ここは「閉じる」を押してスキップすることも可能です)

Vision APIを有効にする

Google CloudのCloud Vision APIページに行き、「有効にする」をクリックしてAPIを有効化します。

なお、事前にGoogle Cloudのプロジェクト作成が必要となります。プロジェクト作成方法については以下の記事を参考にしてみてください。

あわせて読みたい
GASで作ったAPIにM5StackからPOSTする方法
GASで作ったAPIにM5StackからPOSTする方法
API Keyを発行する

Google Cloudのプロジェクトページに行き、「APIとサービス」から「認証情報」をクリックします。

認証情報を作成」から、「APIキー」を選択します。

APIキーが作成されますので、コピーしておきましょう。

GASプロジェクトとGCPプロジェクトを紐づける

GASのプロジェクトとGCPのプロジェクトの紐づけを行います。STEP6でAPIキーを作成しておいたGCPプロジェクトを、今回作成するGASに紐づけます。

紐づけ方法については以下の記事に書いてありますので参考にしていただければ幸いです。

あわせて読みたい
【無料】GASを使い始めるための3ステップ【簡単】
【無料】GASを使い始めるための3ステップ【簡単】

以上でVision APIがGASで使えるようになりました。

ここから実際にGASでスクリプトを書いていきます!

画像からテキストを抽出するGASスクリプト

画像からテキストを抽出する手順は、

  1. 画像をGoogle Driveに保存する
  2. Google Driveに保存した画像のIDを取得する
  3. Vision APIを使ってテキストを抽出する
  4. 抽出したテキストをスプレッドシートに記入する

という流れとなります(画像のURLがダイレクトに取得できる場合は、画像を保存する必要はありません)。

1. 画像をGoogle Driveに保存する

まずは、Google Driveに画像を保存するためのフォルダを作成します。

作成したフォルダに、テキストを抽出したい画像を保存していきましょう。

今回は試しということで、これまでのブログ記事に使用した以下の3つの画像を使用したいと思います。

1つめ
2つめ
3つめ

2. Google Driveに保存した画像のIDを取得する

1で保存した画像のIDを取得します。手動で取得する方法と、GASスクリプトを使って取得する方法どちらも紹介します。

手動で取得する方法

Google Drive上の画像を右クリックし、「リンクを取得」をクリック
リンクをコピー」をクリックする
コピーしたリンクからIDを抽出する

STEP2でコピーしたリンクは以下のようになっています。

https://drive.google.com/file/d/ファイルID/view?usp=share_link

ここからファイルIDを取得することができます。

GASスクリプトを使用して一括取得する方法

フォルダIDを取得する

ブラウザで、画像が保存されているGoogle Driveのフォルダページを開きます。

その状態でブラウザのURL欄を確認してください。

https://drive.google.com/drive/folders/フォルダID

このように、フォルダIDがURLに含まれいていますので、「フォルダID」の部分をコピーしてGASで使用できるようにしておきましょう。

GASスクリプトを書き、実行する

以下のスクリプトは、フォルダIDを指定するとその中にあるファイルについて、

  • ファイル名
  • ファイルID
  • ファイルURL

を抽出することができます。

const FOLDER_ID = "ここにフォルダIDを入れて下さい";

function getFileInfo() {
  const imageFolder = DriveApp.getFolderById(FOLDER_ID);
  const imageFiles = imageFolder.getFiles();
  const fileInfo = [];
  while(imageFiles.hasNext()) {
    const file = imageFiles.next();
    const fileName = file.getName();
    const fileId = file.getId();
    const fileUrl = file.getUrl();
    console.log(`ファイル名:${fileName}, ファイルID:${fileId}, URL:${fileUrl}`)
    fileInfo.push({
      name: fileName,
      id: fileId,
      url: fileUrl
    })
  }
  return fileInfo;
}

実行すると、以下のようにログに出力されます。

3. Vision APIを使ってテキストを抽出する

GASスクリプト

const VISION_API_URL = "https://vision.googleapis.com/v1/images:annotate";
const API_KEY = "ここにAPIキーを入れてください";

// 実行する関数
function main() {
  const fileInfo = getFileInfo();
  console.log(fileInfo);
  fileInfo.forEach(file => {
    const text = extractTextsFromImage(file.id);
    console.log(text);
  })
}

// 画像URLからテキストを抽出する関数
function extractTextsFromImage(fileId) {
  const imageData = DriveApp.getFileById(fileId).getBlob().getBytes();
  const payload = {
    "requests": [
      {
        "image" : {
          "content": Utilities.base64Encode(imageData)
        },
        "features": [
          {
            "type": "TEXT_DETECTION"
          }
        ]
      }
    ]
  }
  const response = JSON.parse(UrlFetchApp.fetch(VISION_API_URL+`?key=${API_KEY}`, {
    'method': 'POST',
    'contentType': 'application/json; charset=utf-8',
    'payload': JSON.stringify(payload)
  }));
  return response.responses[0].fullTextAnnotation.text;
}

実行結果

ログに抽出されたテキストが出力された

4. 抽出したテキストをスプレッドシートに記入する

新たにGoogle Spreadsheetを作成し、スプレッドシートIDを取得しておきます(スプレッドシートIDは、2で紹介した画像のIDの手動での取得方法と同じです)。

スプレッドシートのシートに、名前を付けておきましょう。ここでは、「extractedTexts」という名前としました。

GASスクリプト

const API_KEY = PropertiesService.getScriptProperties().getProperty('API_KEY');
const FOLDER_ID = PropertiesService.getScriptProperties().getProperty('FOLDER_ID');
const SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('SPREADSHEET_ID');
const VISION_API_URL = "https://vision.googleapis.com/v1/images:annotate";

// 実行する関数
function main() {
  const fileInfo = getFileInfo();
  console.log(fileInfo);
  fileInfo.forEach(file => {
    const text = extractTextsFromImage(file.id);
    appendRow([file.name, file.url, text]);
  });
}

// スプレッドシートに1行追加する関数
function appendRow(row) {
  const activeSheet = SpreadsheetApp.openById(SPREADSHEET_ID);
  const sheet = activeSheet.getSheetByName('extractedTexts');
  sheet.appendRow(row);
}

// 画像URLからテキストを抽出する関数
function extractTextsFromImage(fileId) {
  const imageData = DriveApp.getFileById(fileId).getBlob().getBytes();
  const payload = {
    "requests": [
      {
        "image" : {
          "content": Utilities.base64Encode(imageData)
        },
        "features": [
          {
            "type": "TEXT_DETECTION"
          }
        ]
      }
    ]
  }
  const response = JSON.parse(UrlFetchApp.fetch(VISION_API_URL+`?key=${API_KEY}`, {
    'method': 'POST',
    'contentType': 'application/json; charset=utf-8',
    'payload': JSON.stringify(payload)
  }));
  return response.responses[0].fullTextAnnotation.text;
}

// 画像ファイル情報を取得する関数
function getFileInfo() {
  const imageFolder = DriveApp.getFolderById(FOLDER_ID);
  const imageFiles = imageFolder.getFiles();
  const fileInfo = [];
  while(imageFiles.hasNext()) {
    const file = imageFiles.next();
    const fileName = file.getName();
    const fileId = file.getId();
    const fileUrl = file.getUrl();
    console.log(`ファイル名:${fileName}, ファイルID:${fileId}, URL:${fileUrl}`)
    fileInfo.push({
      name: fileName,
      id: fileId,
      url: fileUrl
    })
  }
  return fileInfo;
}

実行結果

テキスト抽出結果がスプレッドシートに転記された!

まとめ

今回は、画像からテキストを抽出するGASスクリプトを書いてみました。さらに、その結果をスプレッドシートに転記することも試してみました。

結果としては、背景がごちゃごちゃしているとうまく文字が拾えなかったりするようでしたが、おおむね抽出できていたように思います。手書きの文字などでも試してみたいですね。

最後までお読みいただきありがとうございました!

このブログを書いている人
えぬ
えぬ
N日後にムキムキになるエンジニア
WebアプリエンジニアとしてIoTシステムを開発中。30代折り返し。 趣味(モノづくり、プログラミング、筋トレ)や子育てのことを主に記事にします。 TOEIC: 900点/第一級陸上無線技術士/第3種電気主任技術者/技術士一次試験合格/基本情報技術者/第2種電気工事士/デジタル技術検定2級(情報・制御)
記事URLをコピーしました