sample_cam_ai.hsp

sample\iron\sample_cam_ai.hsp » Plain Format

;============================================================
;  sample_cam_ai.hsp — Webcam スナップショット → AI 画像認識 → 説明文
;
;  IronHSP 2026 の目玉デモ。本セッションで作ったモジュールを組み合わせる:
;
;    1. iron_camera_mf      Webcam でリアルタイムプレビュー (hspmfcam.dll)
;    2. iron_cam_save       1 ボタンでスナップショット PNG 保存
;    3. iron_ai             OpenAI 互換 API に画像 + プロンプトで問い合わせ
;       (画像対応は gpt-4o / claude-3-5-sonnet / llama-3.2-vision 等)
;
;  Groq の llava-1.5-7b (or llama-3.2-11b-vision) を想定:
;    iron_ai_set_endpoint "https://api.groq.com/openai/v1"
;    iron_ai_set_key "gsk_..."
;    iron_ai_set_model "llama-3.2-11b-vision-preview"
;
;  注意: 画像の multipart upload は今回は base64 data URL 埋め込み方式で
;  実装 (OpenAI chat vision API の標準)。
;============================================================

#include "hsp3_net_64.as"
#include "iron_camera_mf.hsp"
#include "iron_ai.hsp"
#include "iron_hash.hsp"    ; Base64 encode 用

	title "iron_camera_mf + iron_ai 連動デモ"
	screen 0, 720, 600
	font "MS Gothic", 14

	mes "==== Webcam + AI 画像認識 デモ ===="
	mes ""

	; カメラ open
	n_cams = iron_cam_count()
	if n_cams = 0 {
		dialog "Webcam が接続されていません。", 1
		end
	}
	iron_cam_name 0, cam_name
	title "Webcam + AI: " + cam_name

	prev_x = 10
	prev_y = 40
	prev_w = 480
	prev_h = 360

	hcam = iron_cam_open(0, prev_x, prev_y, prev_w, prev_h)
	if hcam < 0 {
		dialog "カメラ 0 を開けませんでした", 1
		end
	}
	iron_cam_set_aspect hcam, 1

	; UI
	pos 500, 40
	objsize 200, 28
	button gosub "Snapshot + AI", *do_snap_ai

	pos 500, 75
	mes "プロンプト:"
	pos 500, 95
	objsize 200, 24
	sdim user_prompt, 1024
	user_prompt = "この画像に何が写っていますか?"
	input user_prompt, 1023, 1, 24

	; iron_ai 設定 (Groq 推奨)
	iron_ai_set_endpoint "https://api.groq.com/openai/v1"
	iron_ai_set_key      "gsk_REPLACE_ME"
	iron_ai_set_model    "llama-3.2-11b-vision-preview"
	iron_ai_set_max_tokens 300

	pos 10, 410
	mes "----- AI 応答 -----"
	pos 10, 435
	sdim reply_text, 16384
	reply_text = "(まだ何もない)"
	mesbox reply_text, 700, 155, 4

	stop

*do_snap_ai
	; 1. スナップショット保存
	iron_cam_save hcam, "cam_snap.jpg"
	reply_text = "[スナップ保存] cam_snap.jpg\n"
	reply_text = reply_text + "[AI 問い合わせ中...]\n"
	objprm 2, reply_text
	await 50

	; 2. ファイルを bload → Base64 encode
	exist "cam_snap.jpg"
	if strsize < 0 {
		reply_text = reply_text + "[error] snapshot ファイル保存失敗\n"
		objprm 2, reply_text
		return
	}
	sdim img_buf, strsize + 16
	bload "cam_snap.jpg", img_buf, strsize
	base64_encode_buf img_buf, strsize
	img_b64 = refstr

	; 3. iron_ai に multimodal (image + text) で問い合わせ
	;    OpenAI Vision 形式の content 配列を messages に埋め込むため
	;    独自の JSON body を構築 (通常の iron_ai_chattext only 想定)
	sdim body, strlen(img_b64) + 4096
	body = "{\"model\":\"llama-3.2-11b-vision-preview\","
	body = body + "\"messages\":[{\"role\":\"user\",\"content\":["
	body = body + "{\"type\":\"text\",\"text\":\"" + user_prompt + "\"},"
	body = body + "{\"type\":\"image_url\",\"image_url\":{\"url\":\"data:image/jpeg;base64,"
	body = body + img_b64 + "\"}}"
	body = body + "]}],\"max_tokens\":300}"

	; Authorization
	http_set_header "Authorization: Bearer gsk_REPLACE_ME\r\n"
	sdim resp_body, 65536
	http_post "https://api.groq.com/openai/v1/chat/completions", body, resp_body, "application/json"
	if stat ! 200 {
		reply_text = reply_text + "[HTTP error] " + stat + "\n"
		objprm 2, reply_text
		return
	}

	; JSON response から choices[0].message.content 抽出
	hid = json_load(resp_body)
	if hid < 0 {
		reply_text = reply_text + "[JSON parse error]\n"
		objprm 2, reply_text
		return
	}
	ai_text = json_str(hid, "choices[0].message.content")
	json_release hid

	reply_text = "[質問] " + user_prompt + "\n\n"
	reply_text = reply_text + "[AI 応答]\n" + ai_text + "\n"
	objprm 2, reply_text
	return