攝影或3C

Python教學:如何把本地圖片傳給 OpenAI Vision API

在使用 OpenAI 的 Vision 模型(例如 gpt-4.1gpt-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 格式的檔頭)。
  • 裡面會有 IHDRIDAT 等 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}}

這裡有三個關鍵點:

  1. data:image/png;base64,
    • data: → 表示這是一個內嵌的資料(而不是網址)。
    • image/png → MIME type,代表這是一張 PNG 圖片(若是 JPG 就用 image/jpeg)。
    • base64, → 告訴解析器後面接的是 base64 字串。
  2. + img_base64
    • 把我們剛剛轉好的 base64 字串拼接上去,這就是圖片的內容。
  3. 整個字串就是一張「嵌入式圖片」
    • 例如:
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)

輸出結果:

⚠️ 常見錯誤

  1. 直接傳 image_bytes
    • 錯誤寫法:
{"url": "data:image/png;base64," + image_bytes.decode("latin1")}
  • 這樣只是把二進位硬轉成亂碼字串,並不是合法的 Base64。

忘記加 MIME type 前綴

  • 錯誤寫法:
{"url": img_base64}
    • API 不知道這是什麼格式,會報 Invalid image (base64) data
  1. 圖片太大
    • 如果圖片超過限制,API 也會拒絕,建議先壓縮或縮小圖片。

🎯 總結

  • 正確流程:讀取圖片 → Base64 編碼 → 加上 data:image/...;base64, 前綴 → 傳給 image_url
  • 最關鍵的地方
"data:image/png;base64," + img_base64

這樣就能保證 API 正確識別你的圖片。

推薦hahow線上學習python: https://igrape.net/30afN

儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡