こんにちは。普段フロントエンドを中心にWeb開発をしている、あいすです。
突然ですが皆さん、画像のalt属性ってちゃんと設定していますか?
私も必要性は十分に理解できるものの、適切な文章を考えるコストがめちゃくちゃ高くて雑にやってしまっている事があります。。。
そこで、GPT-4oの力を借りて、画像から説明を生成してくれるWebアプリを作ってみました。
完成物
以下のURLで確認できます:
技術構成
Vite + TypeScript + Tailwind + Preact
あえてPreactで行ったのは、小規模なSPAなので基本的なフックがあれば十分かな〜と思ったからです。
また、今回はサーバーを立てずに全てクライアントサイドで処理しています。これは、よくわからない個人のサービスに自分の画像を上げるのを躊躇う方も多いのでは?という考えからです。各自でOpenAI API Keyを用意してください。
動作例
プロンプト
そのままでもJSONが返ってきたので、JSONモードにはしていません。
私はWebデザイナーです。imgタグを使ってホームページで添付の画像を紹介しようと思ったのですが、alt属性に何を書けば良いかわかりません。
WCAGのガイドラインに沿って、「写真」「様子」「風景」など、画像の内容を簡潔な言葉で説明してください。
説明は以下のフォーマットで紹介してください。また、詳細な情報があればより良い説明ができる場合は、"status"を"need more infomation"にしてください。
altを生成できた場合
{
"status":"ok",
"alt":画像の説明
}
追加の情報があるとより適切なaltを生成できる場合
{
"status":"need more infomation",
"alt":画像の説明
}
画像の処理
大きすぎる画像はトークンを消費してしまうため、クライアントサイドで画像サイズを変換しています。
const readImage = useCallback((file: File) => {
// 対応ファイルの確認
const avaivableTypes = ["image/png", "image/jpeg", "image/webp"]
if (!avaivableTypes.includes(file.type)) {
toast.error("対応していない画像形式です")
return
}
try {
// 選択画像を縦横比を保ちつつ横幅640pxにリサイズし、URLに変換
const canvas = document.createElement("canvas")
const ctx = canvas.getContext("2d")
if (!ctx) return
const image = new Image()
image.src = URL.createObjectURL(file)
image.onload = () => {
canvas.width = 640
canvas.height = (640 * image.height) / image.width
ctx.drawImage(image, 0, 0, canvas.width, canvas.height)
setImage(canvas.toDataURL("image/jpeg"))
}
} catch (e) {
toast.error("画像の読み込みに失敗しました")
console.error(e)
}
}, [])
トークン使用量を表示する
画像の説明が生成されると、このような表示が行われます。
OpenAIのAPIレスポンスにはusage
というキーが含まれており、その中に使用したトークン量が入っているので、それを表示することで生成にいくらくらいかかったのか可視化できます。
終わりに
画像の説明を書くのは結構大変ですが、生成AIが台頭してきてこういった解決方法も出てきたのは面白いと感じました!
ちなみに、MSEdgeではaltがない画像に自動で説明をつけてくれるようです。こういったブラウザの機能が標準化していけば、開発者・ユーザーのいずれもより便利な世の中になるかもしれないですね。