みんなの水族館!VertexAI基盤モデルImagenとGoogle Drive連携

一日一日を大切に生きたい岡村です。

discordでストイックな友達5人と
毎日の積み上げを共有し合ってます。

共有を忘れないためにリマインド用の
シンプルなbotを作ったのですが、
遊びで機能を増やしているうちに、
あれおかしいな、
「友達が積み上げを共有する度にポイントがたまり、
一定のポイントを超えると
AIが作った海のイラストに魚が増えていく」bot
になってしまいました。

アビスリウム楽しいですよね、大好きです。

岡村のアビスリウム

この機能を実装する際に、
「VertexAI基盤モデルImagenに画像生成をさせ、Google Driveに保存する」
処理が必要になり、
ImagenとGoogle Driveの連携については
まだ記事が少なそうだったので手順を紹介してみます。

Imagen事前準備

Google Cloudから機能を有効にします。

1. ナビゲーションメニュー>APIとサービス>有効なAPIとサービス
の順にクリック

2. APIとサービス>APIとサービスの有効化
の順にクリック

3. 検索ボックス内で「vertex」と入力し、エンター

4. 「Vertex AI API」をクリック

5. 遷移先の画面で「有効にする」をクリック

Google Apps Script事前準備

1. プロジェクトの設定>全般設定>
「appsscript.json」マニフェスト ファイルをエディタで表示する
にチェックを入れる

2. エディタ>ファイル>appsscript.json
の順にクリック

3. 以下をコピペ

{

  "timeZone": "Asia/Tokyo",

  "dependencies": {

  },

  "exceptionLogging": "STACKDRIVER",

  "oauthScopes": ["https://www.googleapis.com/auth/script.external_request","https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/drive"],

  "runtimeVersion": "V8"

}

4. プロジェクトの設定>スクリプトプロパティ>スクリプトプロパティを追加

・1つ目
プロパティ:FOLDER_ID
値:画像を落としたいGoogle DriveのフォルダのURL(folders以下)

・2つ目
プロパティ:PROJECT_NUMBER
値:VertexAIを有効化したGoogleCloudPlatformプロジェクトの番号

コーディング

任意の名前でスクリプトファイルを新規作成し、以下をコピペ

function main () {
  // 生成したい画像の特徴
  // 2023-09-30現在、日本語だと関係ない画像が生成されたため英語で
  const PROMPT = 'Illustration of the bottom of the sea. There is a rock in the center. ';
  const BYTES_BASE64_ENCODED = generateImageByImagen(PROMPT);
  // base64でエンコードされた文字列をUTF-8バイト配列にデコード
  const DATA = Utilities.base64Decode(BYTES_BASE64_ENCODED);
  const CONTENT_TYPE = 'image/png';
  const FILE_NAME = 'bottom of sea';
  // 画像を落としたいフォルダーのURL
  const scriptProperties = PropertiesService.getScriptProperties();
  const FOLDER_ID = scriptProperties.getProperty('FOLDER_ID');
  const FOLDER = DriveApp.getFolderById(FOLDER_ID);
  createFileOnDrive(DATA, CONTENT_TYPE, FILE_NAME, FOLDER);
}

// Imagenで画像生成
function generateImageByImagen(prompt) {
  // GoogleCloudPlatformプロジェクトの番号
  const SCRIPT_PROPERTIES = PropertiesService.getScriptProperties();
  const PROJECT_NUMBER = SCRIPT_PROPERTIES.getProperty('PROJECT_NUMBER');
  // VertexAIのAPIのエンドポイントURL
  const API_URL = `https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_NUMBER}/locations/us-central1/publishers/google/models/imagegeneration:predict`;
  const PAYLOAD = {
    "instances": [
      {
        "prompt": prompt
      }
    ],
    "parameters": {
      "sampleCount": 1
    }
  }
  // payloadやHTTP通信種別、認証情報をoptionで設定
  const options = {
    'payload': JSON.stringify(PAYLOAD),
    'method' : 'POST',
    'muteHttpExceptions': true,
    'headers': {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    'contentType':'application/json'
  };
  // VertexAIにAPIリクエストを送り、結果を変数に格納
  const RESPONSE = JSON.parse(UrlFetchApp.fetch(API_URL, options).getContentText());
  return RESPONSE.predictions[0].bytesBase64Encoded;
}

// ドライブに画像を保存
function createFileOnDrive(bytesUTF8Decoded, contentType, fileName, folder) {
  const BLOB = Utilities.newBlob(bytesUTF8Decoded, contentType, fileName);
  const FOLDER = folder;
  FOLDER.createFile(BLOB);
}

コーディングができましたら、Google Apps Script画面上の
「実行」ボタンをクリックしてみてください。
ドライブに画像が保存されているはずです。

今回のサンプルではプロンプト
’Illustration of the bottom of the sea. There is a rock in the center.’
でリクエストしましたが、
もちろんプロンプト次第で生成される画像は変わってきます。
同じプロンプトでも違ったニュアンスの画像が
生成されたりするので面白いです。

いかがでしたでしょうか。
VertexAIは有料ですが、テストでリクエストを投げまくっても
100円ちょっと超えたくらいなので、勉強がてら触ってみるのも良いかもです。

ああ、なんだかお魚を見て癒やされたくなってきましたね。
水族館に行くのか?それとも
“リコリス・リコイル”第4話を見るのか。

また何か作ったら共有します!

お問い合わせ

サービスに関するご相談やご質問などこちらからお問い合わせください。

03-55107260

受付時間 10:00〜17:00