DelphiでGemini APIを使用してAIに画像を解析してもらう(TNetHTTPClient)
DelphiでGemini API 無料版を使用してAIに画像を送って解析してもらう方法をサンプルソースコードで解説します。
Gemini API 無料版を使用して会話する場合はこちら(TNetHTTPClient使用)又はこちら(TRESTClient使用)
Gemini APIキーの取得
Googleのアカウントを取得しログインします。 次に Google AI Studio にアクセスします。
https://aistudio.google.com/
左下の「Get API key」をクリックし、右上の「API キーを作成」をクリックするとAPIキーを作成することができます。
取得したGemini APIキーは Gemini Free Tier(無料版)ですので1日の回数や1分間の回数制限などがあります。
また無料版は会話の内容を学習に使われる可能性がありますので注意が必要です。
お支払方法を設定すると有料版に切り替わるようです。
Gemini APIに送るJSON
Gemini APIに送るJSONは以下のような形式になります。
{
"contents":[
{
"parts":[
{"text":"この画像には何が写っていますか?"},
{"inlineData":
{"mimeType":"image\/jpeg","data":"Base64エンコードした画像ファイル"}
}
]
}
]
}
フォームデザイン
IDEから[ファイル]⇒[新規作成]⇒[VLC フォーム アプリケーション - Delphi]を選択して新規プロジェクトを作成します。
TImage × 1個、TMemo × 2個、TButton × 2個、TOpenDialog × 1個、TNetHTTPClient × 1個をドラッグ&ドロップします。
ソースコード
以下ソースコードを貼り付けた後、デザインビューの左ペインのオブジェクトインスペクタのイベントから
Form1.OnCreate に FormCreate、Button1.OnClick に Button1Click 、Button2.OnClick に Button2Click を設定します。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
Vcl.Imaging.Jpeg, Vcl.Imaging.PngImage, System.Net.URLClient,
System.Net.HttpClient, System.Net.HttpClientComponent;
type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
Image1: TImage;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Memo2: TMemo;
NetHTTPClient1: TNetHTTPClient;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
img:String;
mime:String;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
const
//API Key を設定する
ApiKey:String='ここに上記で取得したAPIキーを貼り付けます';
implementation
{$R *.dfm}
uses System.NetEncoding, //TNetEncoding.Base64用
Rest.Types, System.JSON, System.JSON.Readers,
System.JSON.Builders,System.JSON.Serializers;
procedure TForm1.Button1Click(Sender: TObject);
var strm:TMemoryStream;
bt:TBytes;
begin
if not OpenDialog1.Execute then exit;
Image1.Picture.LoadFromFile(OpenDialog1.FileName);
if UpperCase(ExtractFileExt(OpenDialog1.FileName))='JPG' then
mime:='image/jpeg'
else
mime:='image/png';
strm:=TMemoryStream.Create;
try
strm.LoadFromFile(OpenDialog1.FileName);
strm.Position:=0;
SetLength(bt,strm.Size);
strm.Read(bt[0],strm.Size);
finally
strm.Free
end;
img:=TNetEncoding.Base64.EncodeBytesToString(bt);
img:=StringReplace(img,#13#10,'',[rfReplaceAll]);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Body,Parts,inlineData,js:TJsonObject;
ContArr,JA1:TJsonArray;
ASource:TStringStream;
res:IHTTPResponse;
JsonStr: String;
sr:TStringReader;
JsonTr:TJsonTextReader;
JsonIt:TJSONIterator;
st:String;
begin
if Trim(Memo1.Text)='' then Exit;
if img='' then Exit;
Body := TJSONObject.Create; // body.ToJSON = '{}'の雛型
try
ContArr := TJSONArray.Create; // { "contents":[] 用 }
Parts:=TJsonObject.Create;
JA1:=TJSONArray.Create;
JA1.Add(TJsonObject.Create.AddPair('text',Memo1.Text));
inlineData:=TJsonObject.Create;
js:=TJsonObject.Create;
js.AddPair('mimeType',mime);
js.AddPair('data',img);
inlineData.AddPair('inlineData',js);
Ja1.Add(inlineData);
Parts.AddPair('parts',JA1);
ContArr.Add(Parts);
Body.AddPair('contents',ContArr);
Body.AddPair('systemInstruction',
TJSONObject.Create.AddPair('parts',
TJSONArray.Create(
TJSONObject.Create.AddPair(
'text',
'マークアップを使わずプレーンテキストで返答してください。')
)
)
);
JsonStr:=Trim(Body.ToJSON());
finally
Body.Free; //親オブジェクトが子オブジェクトを破棄するので親だけ破棄
end;
ASource := TStringStream.Create(JsonStr, TEncoding.UTF8);
try
NetHTTPClient1.ContentType:='application/json';
res:=NetHTTPClient1.Post(
'https://generativelanguage.googleapis.com/v1beta/models/'+
'gemini-3.1-flash-lite:generateContent?key='+ApiKey,
ASource, nil, nil
);
finally
ASource.Free;
end;
sr:=TStringReader.Create(res.ContentAsString(TEncoding.UTF8));
JsonTr:=TJsonTextReader.Create(sr);
JsonIt:=TJsonIterator.Create(JsonTr);
try
JsonIt.Next('candidates');
JsonIt.Recurse;//配列の中に入る
JsonIt.Next;
JsonIt.Recurse;//連想配列の中に入る
JsonIt.Next('content');
JsonIt.Recurse;//連想配列の中に入る
JsonIt.Next('parts');
JsonIt.Recurse;//配列の中に入る
while JsonIt.Next do
begin
JsonIt.Recurse;//連想配列の中に入る
JsonIt.Next('text');
st:=AdjustLineBreaks(JsonIt.AsString);
JsonIt.Return;
end;
JsonIt.Return;
JsonIt.Return;
JsonIt.Return;
JsonIt.Return;
finally
JsonIt.Free;
JsonTr.Free;
sr.Free;
end;
Memo2.Lines.Add(st);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OpenDialog1.Filter:='画像|*.jpg;*.png';
Image1.Proportional:=True;
Image1.Stretch:=True;
Memo1.Clear;
Memo2.Clear;
Button1.Caption:='画像読み込み';
Button2.Caption:='画像について質問';
end;
end.
実行
IDEから[実行]⇒[実行]を選択するとコンパイルされて実行されます。
Button1を押して解析対象画像を選択します。次にMemo1にAIへ解析内容や質問を入力しButton2をクリックするとMemo2にGemini AIから応答があります。
