Skip to content

图像和视觉

概览

在本指南中,你将了解如何使用 OpenAI API 构建与图像相关的应用。
如果你已经明确知道自己要构建什么,可以直接根据下方对应的使用场景开始。如果你还不确定从哪里入手,可以继续阅读本页概览。

图像相关使用场景一览

最新的语言模型已经能够处理图像输入并对其进行分析,这项能力通常称为 视觉(vision)。GPT Image 模型则可以结合文本和图像输入,生成新图像,或对已有图像进行编辑。

OpenAI API 提供了多个端点,既可以将图像作为输入处理,也可以将图像作为输出生成,从而支持你构建强大的多模态应用。

API支持的使用场景
Responses API分析图像,将图像作为输入,并且/或者将图像作为输出生成
Images API生成图像输出,并可选择将图像作为输入
Chat Completions API分析图像,并将图像作为输入生成文本或音频

如需进一步了解各模型支持的输入与输出模态,请参考我们的模型页面

生成或编辑图像

你可以使用 Image API 或 Responses API 生成或编辑图像。

当前最先进的图像生成模型 gpt-image-2,能够理解文本和图像,并结合广泛的世界知识生成高质量图像,具备较强的指令遵循能力与上下文理解能力。

使用 Responses API 生成图像:

javascript
import OpenAI from "openai";
const openai = new OpenAI();

const response = await openai.responses.create({
    model: "gpt-5.4-mini",
    input: "Generate an image of gray tabby cat hugging an otter with an orange scarf",
    tools: [{type: "image_generation"}],
});

// Save the image to a file
const imageData = response.output
  .filter((output) => output.type === "image_generation_call")
  .map((output) => output.result);

if (imageData.length > 0) {
  const imageBase64 = imageData[0];
  const fs = await import("fs");
  fs.writeFileSync("cat_and_otter.png", Buffer.from(imageBase64, "base64"));
}
python
from openai import OpenAI
import base64

client = OpenAI() 

response = client.responses.create(
    model="gpt-5.4-mini",
    input="Generate an image of gray tabby cat hugging an otter with an orange scarf",
    tools=[{"type": "image_generation"}],
)

# Save the image to a file
image_data = [
    output.result
    for output in response.output
    if output.type == "image_generation_call"
]

if image_data:
    image_base64 = image_data[0]
    with open("cat_and_otter.png", "wb") as f:
        f.write(base64.b64decode(image_base64))
bash
openai responses create \
  --model gpt-5.5 \
  --raw-output \
  --transform 'output.#(type=="image_generation_call").result' <<'YAML' | base64 --decode > cat_and_otter.png
tools:
  - type: image_generation
input: Generate an image of a gray tabby cat hugging an otter with an orange scarf.
YAML

你可以在我们的图像生成指南中了解更多内容。

利用世界知识进行图像生成

GPT Image 模型能够利用对现实世界的视觉理解,在没有参考图的情况下生成带有真实细节、更加逼真的图像。

例如,如果你要求 GPT Image 生成一个陈列最受欢迎半宝石的玻璃柜,模型会知道应该选择紫水晶、粉晶、玉石等宝石,并以较为真实的方式表现出来。

图像分析

视觉(Vision) 指的是模型“看见”并理解图像的能力。如果图像中包含文字,模型通常也可以理解这些文字。
它能够理解大多数视觉元素,包括物体、形状、颜色和纹理,当然也仍然存在一些局限性

将图像作为模型输入

你可以通过多种方式把图像作为输入传给生成请求:

  • 提供图像文件的完整 URL
  • 提供 Base64 编码后的 data URL
  • 提供文件 ID(通过 Files API 创建)

你也可以在一次请求中,通过在 content 数组里放入多个图像,实现多图输入。不过要注意,图像也会计入 token,并按此计费。

通过 URL 传入图像

分析图像内容:

javascript
import OpenAI from "openai";

const openai = new OpenAI();

const response = await openai.responses.create({
    model: "gpt-5.4-mini",
    input: [{
        role: "user",
        content: [
            { type: "input_text", text: "what's in this image?" },
            {
                type: "input_image",
                image_url: "https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg",
            },
        ],
    }],
});

console.log(response.output_text);
python
from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-5.4-mini",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "what's in this image?"},
            {
                "type": "input_image",
                "image_url": "https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg",
            },
        ],
    }],
)

print(response.output_text)
csharp
using OpenAI.Responses;

string key = Environment.GetEnvironmentVariable("XIKAPI_API_KEY")!;
OpenAIResponseClient client = new(model: "gpt-5", apiKey: key);

Uri imageUrl = new("https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg");

OpenAIResponse response = (OpenAIResponse)client.CreateResponse([
    ResponseItem.CreateUserMessageItem([
        ResponseContentPart.CreateInputTextPart("What is in this image?"),
        ResponseContentPart.CreateInputImagePart(imageUrl)
    ])
]);

Console.WriteLine(response.GetOutputText());
bash
curl https://xikapi.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XIKAPI_API_KEY" \
  -d '{
    "model": "gpt-5.4-mini",
    "input": [
      {
        "role": "user",
        "content": [
          {"type": "input_text", "text": "what is in this image?"},
          {
            "type": "input_image",
            "image_url": "https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg"
          }
        ]
      }
    ]
  }'
bash
openai responses create \
  --model gpt-5.5 \
  --raw-output \
  --transform 'output.#(type=="message").content.0.text' <<'YAML'
input:
  - role: user
    content:
      - type: input_text
        text: What is in this image?
      - type: input_image
        image_url: https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg
YAML

通过 Base64 编码传入图像

分析图像内容:

javascript
import fs from "fs";
import OpenAI from "openai";

const openai = new OpenAI();

const imagePath = "path_to_your_image.jpg";
const base64Image = fs.readFileSync(imagePath, "base64");

const response = await openai.responses.create({
    model: "gpt-5.4-mini",
    input: [
        {
            role: "user",
            content: [
                { type: "input_text", text: "what's in this image?" },
                {
                    type: "input_image",
                    image_url: `data:image/jpeg;base64,${base64Image}`,
                },
            ],
        },
    ],
});

console.log(response.output_text);
python
import base64
from openai import OpenAI

client = OpenAI()

# Function to encode the image
def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode("utf-8")


# Path to your image
image_path = "path_to_your_image.jpg"

# Getting the Base64 string
base64_image = encode_image(image_path)


response = client.responses.create(
    model="gpt-5.4",
    input=[
        {
            "role": "user",
            "content": [
                { "type": "input_text", "text": "what's in this image?" },
                {
                    "type": "input_image",
                    "image_url": f"data:image/jpeg;base64,{base64_image}",
                },
            ],
        }
    ],
)

print(response.output_text)
csharp
using OpenAI.Responses;

string key = Environment.GetEnvironmentVariable("XIKAPI_API_KEY")!;
OpenAIResponseClient client = new(model: "gpt-5", apiKey: key);

Uri imageUrl = new("https://openai-documentation.vercel.app/images/cat_and_otter.png");
using HttpClient http = new();

// Download an image as stream
using var stream = await http.GetStreamAsync(imageUrl);

OpenAIResponse response1 = (OpenAIResponse)client.CreateResponse([
    ResponseItem.CreateUserMessageItem([
        ResponseContentPart.CreateInputTextPart("What is in this image?"),
        ResponseContentPart.CreateInputImagePart(BinaryData.FromStream(stream), "image/png")
    ])
]);

Console.WriteLine($"From image stream: {response1.GetOutputText()}");

// Download an image as byte array
byte[] bytes = await http.GetByteArrayAsync(imageUrl);

OpenAIResponse response2 = (OpenAIResponse)client.CreateResponse([
    ResponseItem.CreateUserMessageItem([
        ResponseContentPart.CreateInputTextPart("What is in this image?"),
        ResponseContentPart.CreateInputImagePart(BinaryData.FromBytes(bytes), "image/png")
    ])
]);

Console.WriteLine($"From byte array: {response2.GetOutputText()}");

通过文件 ID 传入图像

分析图像内容:

javascript
import OpenAI from "openai";
import fs from "fs";

const openai = new OpenAI();

// Function to create a file with the Files API
async function createFile(filePath) {
  const fileContent = fs.createReadStream(filePath);
  const result = await openai.files.create({
    file: fileContent,
    purpose: "vision",
  });
  return result.id;
}

// Getting the file ID
const fileId = await createFile("path_to_your_image.jpg");

const response = await openai.responses.create({
  model: "gpt-5.4-mini",
  input: [
    {
      role: "user",
      content: [
        { type: "input_text", text: "what's in this image?" },
        {
          type: "input_image",
          file_id: fileId,
        },
      ],
    },
  ],
});

console.log(response.output_text);
python
from openai import OpenAI

client = OpenAI()

# Function to create a file with the Files API
def create_file(file_path):
  with open(file_path, "rb") as file_content:
    result = client.files.create(
        file=file_content,
        purpose="vision",
    )
    return result.id

# Getting the file ID
file_id = create_file("path_to_your_image.jpg")

response = client.responses.create(
    model="gpt-5.4-mini",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "what's in this image?"},
            {
                "type": "input_image",
                "file_id": file_id,
            },
        ],
    }],
)

print(response.output_text)
csharp
using OpenAI.Files;
using OpenAI.Responses;

string key = Environment.GetEnvironmentVariable("XIKAPI_API_KEY")!;
OpenAIResponseClient client = new(model: "gpt-5", apiKey: key);

string filename = "cat_and_otter.png";
Uri imageUrl = new($"https://openai-documentation.vercel.app/images/{filename}");
using var http = new HttpClient();

// Download an image as stream
using var stream = await http.GetStreamAsync(imageUrl);

OpenAIFileClient files = new(key);
OpenAIFile file = await files.UploadFileAsync(BinaryData.FromStream(stream), filename, FileUploadPurpose.Vision);

OpenAIResponse response = (OpenAIResponse)client.CreateResponse([
    ResponseItem.CreateUserMessageItem([
        ResponseContentPart.CreateInputTextPart("what's in this image?"),
        ResponseContentPart.CreateInputImagePart(file.Id)
    ])
]);

Console.WriteLine(response.GetOutputText());

图像输入要求

输入图像需要满足以下要求,才能在 API 中正常使用。

支持的文件类型 - PNG (`.png`) - JPEG (`.jpeg` 和 `.jpg`) - WEBP (`.webp`) - 非动态图 GIF (`.gif`)
大小限制 - 单次请求总载荷最多 512 MB - 单次请求最多 1500 张单独图像输入
其他要求 - 不包含水印或 Logo - 不包含 NSFW 内容 - 清晰到足以让人类理解

选择图像细节级别

detail 参数用于告诉模型在处理和理解图像时使用什么精度级别(lowhighoriginalauto)。如果你省略该参数,模型会使用 auto。在 Responses API 和 Chat Completions API 中,这一行为是一致的。在 gpt-5.5 上,auto 和默认省略参数的行为等价于 original

选择细节级别时可参考下表:

细节级别最适合的场景
low当不需要精细视觉细节时,用于快速、低成本地理解图像。模型接收的是 512px x 512px 的低分辨率版本。
high标准高保真图像理解。
original适合大尺寸、信息密集、空间敏感,或计算机使用(computer-use)类图像。适用于 gpt-5.4 及未来模型。
auto自动选择细节级别。在 gpt-5.5 上,auto 与默认省略时都等价于 original

对于 gpt-5.4 及未来模型上的计算机使用、定位与点击精度场景,我们建议使用 "detail": "original"。详见计算机使用指南

关于模型如何缩放图像,可继续阅读下方的模型尺寸行为;关于 token 成本,可阅读后面的成本计算

模型尺寸行为

不同模型在图像 token 化前,使用的缩放规则并不相同:

模型家族支持的细节级别Patch 与缩放行为
gpt-5.5low, high, original, autohigh 最多允许 2,500 个 patch,或最大边长 2048 像素。 original 最多允许 10,000 个 patch,或最大边长 6000 像素。 如果超出任一限制,我们会在保留宽高比的前提下,对图像进行缩放,使其满足所选细节级别下两个约束中更严格的那个。auto 与省略 detail 时,使用与 original 相同的缩放行为。
gpt-5.4low, high, original, autohigh 最多允许 2,500 个 patch,或最大边长 2048 像素。 original 最多允许 10,000 个 patch,或最大边长 6000 像素。 如果超出任一限制,我们会在保留宽高比的前提下,对图像进行缩放,使其满足所选细节级别下两个约束中更严格的那个。auto 与省略 detail 时,使用与 high 相同的缩放行为。
gpt-5.4-minigpt-5.4-nanogpt-5-minigpt-5-nanogpt-5.2gpt-5.3-codexgpt-5-codex-minigpt-5.1-codex-minigpt-5.2-codexgpt-5.2-chat-latesto4-mini,以及 2025-04-14 快照版本的 gpt-4.1-minigpt-4.1-nanolow, high, autohigh 最多允许 1,536 个 patch,或最大边长 2048 像素。 如果超出任一限制,我们会在保留宽高比的前提下,对图像进行缩放,使其满足两个约束中更严格的那个。
GPT-4oGPT-5.4GPT-4o-minicomputer-use-preview,以及除 o4-mini 外的 o 系列模型 low, high, auto 使用基于 tile 的缩放行为。详见后文对应说明。

成本计算

图像输入与文本输入类似,也是按照 token 单位计量和计费。图像如何转换为文本 token 输入,取决于具体模型。你可以在价格页面的 FAQ 中找到视觉定价计算器。

基于 patch 的图像 token 化

某些模型会通过 32px x 32px 的 patch 覆盖整张图像来完成 token 化。每个模型都有一个最大的 patch 预算。图像的 token 成本按以下方式确定:

A. 计算覆盖原始图像所需的 32px x 32px patch 数量。patch 可以超出图像边界。

text
original_patch_count = ceil(width/32)×ceil(height/32)

B. 如果原始图像会超出模型的 patch 预算,则按比例缩小图像直到满足预算。然后再调整缩放比例,以确保在转换为整数像素维度并重新计算 patch 覆盖数之后,最终尺寸仍在预算内。

text
shrink_factor = sqrt((32^2 * patch_budget) / (width * height))
adjusted_shrink_factor = shrink_factor * min(
  floor(width * shrink_factor / 32) / (width * shrink_factor / 32),
  floor(height * shrink_factor / 32) / (height * shrink_factor / 32)
)

C. 将调整后的缩放比例转换为整数像素尺寸,然后计算覆盖缩放后图像所需的 patch 数量。这个缩放后的 patch 数,就是应用模型倍率前的图像 token 数,并且不会超过模型的 patch 预算。

text
resized_patch_count = ceil(resized_width/32)×ceil(resized_height/32)

D. 按模型对应倍率计算最终 token 总数:

模型倍率
gpt-5.4-mini1.62
gpt-5.4-nano2.46
gpt-5-mini1.62
gpt-5-nano2.46
gpt-4.1-mini*1.62
gpt-4.1-nano*2.46
o4-mini1.72

* 对于 gpt-4.1-minigpt-4.1-nano,这里指的是 2025-04-14 快照版本。

对于 patch 预算为 1,536 的模型,成本计算示例:

  • 一张 1024 x 1024 图像,缩放后 patch 数为 1024

    • A. original_patch_count = ceil(1024 / 32) * ceil(1024 / 32) = 32 * 32 = 1024
    • B. 1024 低于 1,536 的 patch 预算,因此无需缩放
    • C. resized_patch_count = 1024
    • 应用模型倍率前的 patch 数:1024
    • 之后再乘以模型 token 倍率,即可得到最终计费 token
  • 一张 1800 x 2400 图像,缩放后 patch 数为 1452

    • A. original_patch_count = ceil(1800 / 32) * ceil(2400 / 32) = 57 * 75 = 4275
    • B. 4275 超出了 1,536 的 patch 预算,因此先计算 shrink_factor = sqrt((32^2 * 1536) / (1800 * 2400)) = 0.603
    • 然后进一步调整缩放比例,确保最终整数像素尺寸在 patch 计算后仍不超预算:adjusted_shrink_factor = 0.603 * min(floor(1800 * 0.603 / 32) / (1800 * 0.603 / 32), floor(2400 * 0.603 / 32) / (2400 * 0.603 / 32)) = 0.586
    • 缩放后的整数像素尺寸:1056 x 1408
    • C. resized_patch_count = ceil(1056 / 32) * ceil(1408 / 32) = 33 * 44 = 1452
    • 应用模型倍率前的 patch 数:1452
    • 最终再乘以模型倍率,得到计费 token

基于 tile 的图像 token 化

GPT-4o、GPT-5.4、GPT-4o-mini、CUA 和 o 系列(不含 o4-mini)

图像的 token 成本由两个因素决定:尺寸与细节级别。

任何设置为 "detail": "low" 的图像,都会消耗一个固定的基础 token 数,该数值因模型而异。
如果图像设置为 "detail": "high",其成本计算方式如下:

  • 按原始宽高比缩放,使图像落在 2048px x 2048px 的边界框内
  • 再继续缩放,使图像短边为 768px
  • 统计图像中包含多少个 512px 的方块,每个方块都会消耗固定数量 token
  • 最后再加上基础 token
模型基础 tokensTile tokens
gpt-5, gpt-5-chat-latest70140
4o, 4.1, 4.585170
4o-mini28335667
o1, o1-pro, o375150
computer-use-preview65129

GPT Image 1

对于 GPT Image 1,图像输入成本的计算方式与上面类似,不同之处在于会把图像缩放到短边 512px,而不是 768px。
实际价格取决于图像尺寸以及input fidelity

当 input fidelity 设置为 low 时,基础成本是 65 个图像 token,每个 tile 成本是 129 个图像 token。
当使用 high input fidelity 时,除了上述图像 token 外,还会根据图像长宽比增加额外 token:

  • 如果图像是正方形,额外增加 4160 个输入图像 token
  • 如果更接近竖图或横图,额外增加 6240 个 token

图像输入 token 的具体价格,请参考我们的价格页面

局限性

虽然具备视觉能力的模型已经非常强大,并且可以用于许多场景,但你仍然需要了解这些模型的限制。以下是一些已知局限:

  • 医学图像:模型不适合解释 CT 等专业医学图像,也不应被用于医疗建议
  • 非英语文字:当图像中包含日语、韩语等非拉丁字母文本时,模型表现可能不够理想
  • 小文字:建议放大图像中的文字以提升可读性;如果可用,使用 "detail": "original" 也有助于提升效果
  • 旋转问题:模型可能会误解旋转或倒置的文字与图像
  • 视觉元素:当图表或文本依赖颜色、线型(如实线、虚线、点线)变化表达信息时,模型可能难以准确理解
  • 空间推理:模型不擅长需要精确空间定位的任务,例如识别国际象棋棋盘位置
  • 准确性:在某些场景中,模型可能会生成不正确的描述或标题
  • 图像形状:模型对全景图和鱼眼图的处理能力较弱
  • 元数据与缩放:模型不会处理原始文件名或元数据;并且会根据图像大小与 detail 级别,在分析前对图像进行缩放,因此原始尺寸可能发生变化
  • 计数:模型对图像中的物体数量通常只能给出近似值
  • 验证码(CAPTCHA):出于安全原因,我们的系统会阻止 CAPTCHA 的提交

我们会在 token 层面处理图像,因此每张处理过的图像都会计入你的每分钟 token 限额(TPM)。

如需获取最准确、最新的图像处理成本估算,请使用我们的图像定价计算器