GPT-4 Turbo with visionでFigma上の画像の文字を読み取ってみる

## はじめに
こんにちは。
株式会社 運動通信社にて、WEBデザインチームのフロントエンドエンジニアとして業務に取り組んでいる者です。

最近フロントエンドエンジニアメンバー内で、いわゆるAIと呼ばれるツールを使って開発の効率を上げていこうという試みを始めています。
ChatGPTを筆頭に、Github CopilotやGoogleのBardなど多くのAIが登場しています。
最近ではAmazonからもQと呼ばれる生成AIが登場したそうです。

今回はWEBデザインチームということで、弊社でデザインツールとして用いているFigmaとAIを掛け合わせて何か作ってみようと思います。
作ったことの無い
- Figma plugin
- GPT API
この2つを一気に試そうと思える様々なAIには感謝しかないです🙏

デザインということで、テキストというよりは図や画像などがメインとなるかと思うので`GPT-4 Turbo with vision`というモデルを使ってみたいと思います。

## GPT-4 Turbo with visionについて
2023年11月6日に行われたOpenAI DevDayにて発表された比較的新しいモデルです。
特徴としては、
- 画像を入力として扱える
    - base64形式の画像も可能
    - png, jpg, webp, gifに対応
    - アップロードは1枚あたり最大20Mまで
- 価格は入力画像サイズに依存
    - 例： 1080px×1080pxの場合は$0.00765かかる
- いくつかのパラメータが使えないなどの制限あり
- 画像内の位置に関する質問には弱い(椅子はどこにある？など)
- 日本語や韓国語などの非英語に弱い
- 低解像度、高解像度、自動判断の設定がある
    - この設定によって読み取れる内容が変わりそう

などなど。
文章のみだった入力が、画像も可能になることでより多くの用途で使える可能性が高まりました。
まだpreview版とのことで、本格的な運用はまだ検討すべきという点にお気をつけください。

## できあがったもの
figma上の選択した画像から文字列を読み取り、テキストとして表示するものを作ってみました。
img要素のalt属性などに画像内の文章を入力したりするのですが、そういう時に使えればいいなという軽い気持ちです。
![画面収録 2023-12-01 1.46.59 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226532/c2dacaa2-a226-68e6-ab73-d93d2bede661.gif)
現状一般公開の予定はありません。調整がまだまだ必要な仕上がりです。
※GPTのAPI keyについてはローカルでのみ動かしているためあまり気にしていませんが、一般公開する場合の実装については各自で調査頂けますと幸いです。

## 仕組み
figma pluginのAPIを用いて画像をbase64形式に変換し、それをGPT APIへ送信しています。
その後にGPTが読み取った結果が返ってきて、figma pluginで作成したUI上に表示されるという流れになります。
![Group 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226532/dcead3e2-0248-417e-3dbf-7f35bc8ec7ea.png)

## 精度について
GPT-4 Turbo with vision は日本語だと正しい動作が出来ない時があるとのことでしたので、いくつかの画像を試してみました。

指示の文章については下記のようにしています。
```
画像の中の文字列を表示してください。出力は画像内の文字のみとします。
推測で文章を生成せず、読み取れない文章は出力しないでください。
```

### 1つめ
![service_sportsbull.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226532/087647d6-cd59-a009-f17f-8f0319fd12c5.png)
弊社の主要コンテンツの1つ、SPORTSBULLの画像です。
ロゴも独特な文字の形をしています。
更にはスマートフォンの中身の文字も読み取るのでしょうか。
#### 結果
```
画像内に表示されている文字列は以下の通りです。

SPORTS BULL
RESPECT YOU, au

残念ながら、スマートフォン画面に写っているテキストは小さすぎて読み取れません。
```
サービス名とコピー文は問題なく取れていそうです！
スマートフォンの内容に関しては読み取れない判断をしています。
推測で文章を生成されては困るのでこの判断はアリですね。

### 2つめ
![Group 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226532/3ed5e750-1f28-18a7-2535-150314e2da65.png)
こちらも弊社コンテンツの1つ、ANYTEAMの[キャンペーンLP](https://anyteam.jp/campaign/cheer2023)の一部です。
文章が比較的含まれているこの画像は一通り読み取ってほしいところです。
#### 結果
```
虚弱が消えた、あの日。

「ガンバレ！」って、大声で励まされた。

「信じれんな！」って、もっと青背中を押したかった。

「よくやった！」って、力いっぱい褒めたかった。

あの日々を振り返るたびに。

さあ、思いっきり、思いっきり。

心の奥から、声をしてこう。
```
「虚弱が消えた」
「信じれんな」...？

応援とは程遠い文章が返ってきました。
大枠は出来上がっているものの、この感じではまだ実用には難しいか...？

## 3つめ
![sp_header.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226532/80494eba-24ba-ad32-0053-82ea62b018e0.jpeg)
先日、都道府県大会が終了した春高バレーのヘッダー画像です。
年明けには全国大会が始まりますので一緒に盛り上がっていきましょう❤️‍🔥

alt画像にテキストを入れることで、見出し要素の代替テキストの役目も果たしてくれます。
- 第76回
- 全日本バレーボール 高等学校選手権大会
- 2023年10月22日 - 11月23日

このあたりが取れていれば問題なさそうです。

#### 結果
```
VIRUTAL 羽田
VOLLEYBALL
バーチャルバレーボール
フジテレビ
SPORTS BULL
第76回
全日本バレーボール
高等学校選手権大会
開催日程 2023年10月22日 - 11月23日
JVA2023-10-094
```
羽田という謎のワードが最初に来ていますが、ほしい部分は正常に取れていそうです。

## 結論
「調整の余地は多いが、使えなくはない」というのが個人的な感想です。
長い文章にはまだ弱いみたいですが、短めの文章であったり、単語には比較的ちゃんと読み取ってくれました。
あとは指示文を英語で書き換える、画像の解像度を`high`にしてみるなどでも結果は異なりそうですので、もう少し調整をしていきます。

Figmaとの掛け合わせに関しても相性は悪くないのかなと感じています。
今回は文字列を読み取るという話でしたが、コンポーネントを見てデザインやアクセシビリティのレビューであったり、コードに落とし込むなどの可能性もありそうでしたので、そちらにも機会があれば試してみようと思います。

## 余談：躓きポイント
ここからは実装で躓いたポイントをいくつか共有させてください。
### GPT APIが起動しない
まずはFigmaを介さずにGPT APIを動かそうとしたのですが、エラーが返ってくるばかり。
色々と調べてみると、OpenAIのAPIのほうにも支払い情報及び少しばかりのお金を追加する必要がありました。
![スクリーンショット 2023-12-01 3.33.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226532/d0ee580d-801a-9ac0-6db5-c3c7ab987d5a.png)
これによってAPIが正常な挙動をしてくれました。
ちなみに今回は実装も[Cursor](https://cursor.sh/)というAIエディターに自分のAPI keyを設定して使ってみました。
検証でAPIを叩いたりも含めて2.5$ほどになっています。

### Figma pluginからAPIにリクエストを飛ばせない
プラグインのui上でボタンを押下した後に、fetch APIでGPT APIにリクエストを飛ばすのですが、下記のようなエラーが出ていました。
```
Refused to connect to 'https://api.openai.com/v1/chat/completions' because it violates the following Content Security Policy directive: "default-src data: blob:". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
```
他のプラグインなどでは利用できているのになぜだろう...と悩んでいましたが、解決方法は公式のドキュメントに書いてありました。
> To specify a list of domains that your plugin is allowed to access, you update the plugin's manifest.json file:

manifest.jsonにアクセス許可のドメインを追加してという旨が記載あり、こちらを試してみたところ無事に通りました。
ちゃんとドキュメントは見るべきですね...
``` json
{
  ...
  "editorType": [
    "figma",
    "figjam"
  ],
  "ui": "ui.html",
  "networkAccess": {
    "allowedDomains": ["https://api.openai.com/v1/chat/completions"]
  }
}
```

## 参考資料
大変参考にさせていただきました。ありがとうございます🙇‍♂️

https://aitechworld.info/gpt-4-turbo-with-vision/

https://zenn.dev/ixkaito/articles/how-to-make-a-figma-plugin#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%8C%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%8B

https://recruit.gmo.jp/engineer/jisedai/blog/gpt-4-turbo-with-vision/

https://stackoverflow.com/questions/75650840/openai-chatgpt-gpt-3-5-api-error-400-bad-request-migrating-from-gpt-3-api

https://openai.com/blog/new-models-and-developer-products-announced-at-devday

https://platform.openai.com/docs/guides/vision

https://www.figma.com/plugin-docs

## 運動通信社について
運動通信社は「日本を世界が憧れるスポーツ大国にする」というビジョンを達成するべく、一緒に働く仲間を募集しています！
PMやWebエンジニアなど色んな職種を募集しておりカジュアル面談大歓迎なので是非採用フォームよりご連絡ください！
ぜひ一緒に、自分たちも世の中もワクワクするサービスを作りましょう！

https://sportsbull.jp/about/#recruit