在使用 OpenAI 的 Vision 模型(例如 gpt-4.1
、gpt-4o
)時,
若要上傳本地圖片,API 不接受直接傳檔案路徑,
而是需要你把圖片轉換成 Base64 編碼字串,再透過 image_url
格式傳送。
🔍 什麼是 Base64?
- 圖片本質是二進位檔案(bytes)。
- 但 API 要求「純文字」格式來傳輸圖片。
- 因此我們需要把圖片的 bytes 轉換成一個 Base64 編碼字串。
- 然後再加上 MIME type 前綴(例如
data:image/png;base64,
)。
這樣 API 就知道:
👉 這是一張 PNG 圖片,而且內容是 base64 編碼的。
✅ 實作步驟
1. 讀取圖片並轉成 Base64
import base64
image_path = r"D:\Temp\圖片1.png"
with open(image_path, "rb") as f:
image_bytes: bytes = f.read()
# 這裡是 raw bytes
image_bytes_b64: bytes = base64.b64encode(image_bytes)
# base64 後依然是 bytes
img_base64: str = image_bytes_b64.decode("utf-8")
# decode 成字串
這裡:
f.read()
→ 讀取二進位圖片內容。base64.b64encode(image_bytes)
→ 把二進位轉成 Base64(還是 bytes)。.decode("utf-8")
→ 轉成 Python 的字串,方便拼接。
1. image_bytes
(原始檔案 bytes)
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR...'
這是 PNG 檔案的 原始二進位資料。
- 前 4 bytes:
89 50 4E 47
(PNG 格式的檔頭)。 - 裡面會有
IHDR
、IDAT
等 chunk。 - 適合存檔或用影像處理工具讀取。
- 缺點:不能直接放到 JSON 或文字欄位,因為裡面有非 ASCII 碼。
2. image_bytes_b64
(base64 編碼後,仍是 bytes 型別)
b'iVBORw0KGgoAAAANSUhE...'
這個是把原始 bytes 轉成 base64 編碼,但 Python 還是用 b''
包起來,所以型別是 bytes。
- 內容只包含 ASCII 可打印字元(A–Z, a–z, 0–9, +, /, =)。
- 可以安全地放進 JSON / HTTP 傳輸。
- 缺點:比原始檔案大約多 33%。
3.
img_base64
(base64 字串,str 型別)iVBORw0KGgoAAAANSUhE...
這是把上一步的 base64 bytes decode 成 UTF-8 字串。
- 沒有
b''
,型別是str
。 - API(例如 OpenAI GPT Vision)通常要這種格式。
- 可以安全地放進 JSON,例如:
{
"image_url": {
"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhE..."
}
}
image_bytes
= 原始檔案二進位 → 適合存檔、處理。image_bytes_b64
= base64 編碼後,但還是 bytes → 適合再 decode 成字串。img_base64
= base64 編碼後的字串 (str) → 適合放到 API/JSON 傳輸。
👉 所以在 GPT Vision API 呼叫時,你應該用 img_base64
(也就是最後那個 str
)。
2. 準備 image_url
參數
{"type": "image_url",
"image_url": {"url": "data:image/png;base64," + img_base64}}
這裡有三個關鍵點:
data:image/png;base64,
data:
→ 表示這是一個內嵌的資料(而不是網址)。image/png
→ MIME type,代表這是一張 PNG 圖片(若是 JPG 就用image/jpeg
)。base64,
→ 告訴解析器後面接的是 base64 字串。
+ img_base64
- 把我們剛剛轉好的 base64 字串拼接上去,這就是圖片的內容。
- 整個字串就是一張「嵌入式圖片」
- 例如:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
3. 呼叫 GPT Vision API
先建立client
(OpenAI, AzureOpenAI方法不同):
from openai import OpenAI, AzureOpenAI
#dic_api_key 為讀取外部資料,內含api key等資料
if config["Azure_LLM"]:
llm_config = dic_api_key['AzureOpenAI_gpt-4.1']
model_LLM = llm_config['model']
# 部署名稱或你設定的deployment name
endpoint_LLM = llm_config['Target URI']
api_key_LLM = llm_config['api_key']
api_version_LLM = llm_config['api-version']
# 從info文件取用
# 建立 Azure OpenAI Client 用於 LLM(使用info中的api-version)
client_LLM = AzureOpenAI(
api_key=api_key_LLM,
azure_endpoint=endpoint_LLM,
api_version=api_version_LLM
)
print(f"使用 Azure OpenAI 服務的 {model_LLM} 作為 LLM")
else:
# 使用標準 OpenAI API
client_LLM = OpenAI(api_key=dic_api_key['OpenAI']['api_key'])
model_LLM = "gpt-4.1-nano" # 預設模型,可按需調整
print("使用標準 OpenAI API 作為 LLM,請注意流量費用")
#使用自費方案的話,先用input() 停住,待使用者確認
confirm = input("使用標準 OpenAI API 作為 LLM,請注意流量費用,按enter鍵繼續")
呼叫 GPT Vision
# 呼叫 GPT Vision
response = client_LLM.chat.completions.create(
model=model_LLM, # 例如 "gpt-4.1" 或 "gpt-4o"
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "這是一張什麼樣的 block diagram?請只輸出一個標籤,例如:backplane_board_block_diagram / motherboard_block_diagram / others"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64," + img_base64}}
]
}
],
max_tokens=100
)
print("模型輸出標籤:", response.choices[0].message.content)
輸出結果:
⚠️ 常見錯誤
- 直接傳
image_bytes
- 錯誤寫法:
{"url": "data:image/png;base64," + image_bytes.decode("latin1")}
- 這樣只是把二進位硬轉成亂碼字串,並不是合法的 Base64。
忘記加 MIME type 前綴
- 錯誤寫法:
{"url": img_base64}
-
- API 不知道這是什麼格式,會報
Invalid image (base64) data
。
- API 不知道這是什麼格式,會報
- 圖片太大
- 如果圖片超過限制,API 也會拒絕,建議先壓縮或縮小圖片。
🎯 總結
- 正確流程:讀取圖片 → Base64 編碼 → 加上
data:image/...;base64,
前綴 → 傳給image_url
。 - 最關鍵的地方:
"data:image/png;base64," + img_base64
這樣就能保證 API 正確識別你的圖片。
推薦hahow線上學習python: https://igrape.net/30afN