※知り合い向けに書いた記事を公開しています。後から文体など修正予定です🙏
この記事では、アプリ内で撮った写真をOpenAIのAPIに投げる機能の実装をしていくよ!!!
目次:
Part1. カメラで撮影した写真を表示する
Part2. OpenAI APIのセットアップ
Part3. 画像をOpenAIのAPIに送信する ←ここ!
OpenAIから返ってきたテキストを表示する用のTextLabelを二つ目の画面に配置しよう!
配置したTextLabelをコードにも書こう!
PhotosViewController.swiftに以下のコードを追加して、関連付けも行おう!💨
@IBOutlet weak var generatedTextLabel: UILabel!
OpenAIとのやりとりをするコードを書こう!
まずはOpenAIに画像を投げるコードを書く新しいファイルを作っていくよ!
アプリ名の書いてあるフォルダを二本指クリック -> 「New File from Template...」をクリック!
ファイル名は「MachineLearningHelper」としよう!
余談:🧐どうして新しいファイルを作ってコードを書くの?
... 理由は「整理してわかりやすくするため」だよ!
たとえば、ノートに何でも全部書き込んじゃうと、ごちゃごちゃしてどこに何があるかわからなくなるよね?それと同じで、プログラムも一つの場所に全部書くと、あとから見ると大変💦
だから、「このファイルはOpenAIとやりとりをするコードだけ!」ってふうに、役割ごとにファイルを分けると、
- どこに何のコードがあるかわかりやすい
- 直したり追加したりしやすい
- 他の人も読みやすい
っていういいことがたくさんあるよ!!
ファイルが作れたら以下のコードを書こう!
import OpenAI
import UIKit
// 機械学習を手伝ってくれるクラス(1つだけ作ってどこでも使えるようにするために)
class MachineLearningHelper {
static let shared = MachineLearningHelper()
// OpenAIを使うための設定。YOUR_API_KEYの代わりに自分のAPIキーを入力する
private let openAI = OpenAI(apiToken: "YOUR_API_KEY")
// 画像をもとに、AIに「何が映っているか」を説明してもらう関数
// 質問のテキストをカスタマイズしてみよう!
func generateTextfromImage(imageData: Data) async -> String {
do {
// ChatGPT(GPT-4o)に、画像と質問を送って、答えをもらう
let query = ChatQuery(messages: [
.user(.init(content: .vision([
// 質問のテキスト
.chatCompletionContentPartTextParam(.init(text: "以下の画像には何が映っていますか?説明してください。")),
// 画像のデータを送る
.chatCompletionContentPartImageParam(.init(imageUrl: .init(url: imageData, detail: .auto)))
])))
], model: .gpt4_o, maxTokens: 100) // モデルにGPT-4oを指定。最大トークン数は100
// ChatGPTに質問を送り、返事を待つ
let result = try await openAI.chats(query: query)
// 答えを取り出してテキストとして返す
if let choice = result.choices.first,
let text = choice.message.content {
return text
}
} catch {
// もし失敗したら、エラー内容を出力
print("分析失敗: \(error)")
}
// うまくいかなかった時の出力
return "分析に失敗しました"
}
}
作ったMachineLearningHeleperの関数を実際に使っていくよ!
PhotosViewController.swiftを開いて、 「// ここから先を追加」と書かれているコードを追加しよう!
import UIKit
class PhotosViewController: UIViewController {
@IBOutlet var imageView: UIImageView!
@IBOutlet var generatedTextLabel: UILabel! // 生成されたテキスト表示用label
var takenImage: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = takenImage
// ここから先を追加
// takenImage があるなら API を呼ぶ
if let image = takenImage,
let imageData = image.jpegData(compressionQuality: 0.8) {
Task {
// さっき作ったgenerateTextfromImage関数で画像からテキストを生成
let resultText = await MachineLearningHelper.shared.generateTextfromImage(imageData: imageData)
// labelに生成されたテキストを入れる
DispatchQueue.main.async {
self.generatedTextLabel.text = resultText
}
}
}
}
}
buildして試してみよう!
カメラを使うアプリはsimulatorでは使えないよ!実機で試してみよう!
こんな感じで表示されたら成功!OpenAIに投げるテキストをカスタマイズしてみよう!