API cho hình ảnh và video
This content is not available in your language yet.
Mục tiêu
Phần tiêu đề “Mục tiêu”Sau bài này, bạn sẽ:
- Gửi được một tấm ảnh cho mô hình nhìn được ảnh (vision): đặt ảnh vào
messagesdưới dạng data URL base64, cạnh câu hỏi bằng chữ. - Sinh được ảnh từ prompt bằng
images.generate, đọc kết quảb64_jsonvà lưu ra tệp. - Giải thích được vì sao video là một tác vụ bất đồng bộ (asynchronous job): gửi yêu cầu, giữ
id, hỏi lại trạng thái bằng polling, tải kết quả về kịp lúc. - Nhận ra các giới hạn quanh ảnh và video do AI tạo: kiểm duyệt nội dung (content moderation), bản quyền, và vì sao dấu nguồn gốc như C2PA không phải bằng chứng ảnh thật hay giả.
Cần biết trước
Phần tiêu đề “Cần biết trước”- Using Text Generation APIs, in Large Language Models(Not translated yet) (Learned)
Trực giác
Phần tiêu đề “Trực giác”Bạn đã biết gửi chữ cho mô hình và nhận chữ về. Giờ có ba yêu cầu mới:
- Chụp một tờ hóa đơn, hỏi mô hình “tổng tiền là bao nhiêu?”.
- Nhờ mô hình vẽ một bức tranh màu nước cho bài blog.
- Nhờ mô hình làm một đoạn video tám giây.
Nghe thì giống nhau: gửi yêu cầu, nhận kết quả. Nhưng ở tầng API, đó là ba con đường khác nhau.
Hỏi về ảnh vẫn là một cuộc chat. Bạn vẫn gọi chat.completions, chỉ khác là tin nhắn của bạn giờ gồm hai phần: một câu hỏi và một tấm ảnh. Mô hình trả lời bằng chữ, như mọi lần.
Sinh ảnh đi qua một cánh cửa khác: images.generate. Vào là prompt, ra là byte của một tấm ảnh. Không có messages, không có lượt hội thoại. Nhiều người tưởng chỉ một API làm được cả hai việc, rồi bối rối khi mô hình chat trả về một đoạn mô tả thay vì một bức tranh.
Video thì lâu: một lần dựng có thể mất vài phút. Không ai giữ kết nối mở chừng ấy thời gian. Nó giống gửi bưu kiện: bạn gửi đơn, nhận mã vận đơn, thỉnh thoảng tra xem hàng tới đâu. Hàng tới kho thì phải lấy ngay, vì kho chỉ giữ một thời gian ngắn.
Bài toán của bài này là: với SDK openai quen thuộc, gửi được ảnh cho mô hình đọc, xin được ảnh mới từ prompt, và hiểu cách chờ một kết quả dài như video, kèm các giới hạn về an toàn và nguồn gốc của nội dung do AI tạo.
Lý thuyết
Phần tiêu đề “Lý thuyết”Đưa ảnh vào messages
Phần tiêu đề “Đưa ảnh vào messages”Ở bài trước, content của một lượt là một chuỗi. Muốn gửi ảnh, content của lượt user trở thành danh sách các phần (content parts). Mỗi phần có type:
{ "role": "user", "content": [ { "type": "text", "text": "Ảnh có những hình gì, màu gì, nằm ở đâu?" }, { "type": "image_url", "image_url": { "url": "data:image/png;base64,iVBORw0KGgo..." } } ]}Một lượt có thể trộn nhiều phần chữ và nhiều ảnh. Mô hình đọc chúng theo thứ tự rồi trả lời bằng chữ: lượt assistant vẫn có content là chuỗi như bài trước.
Trường url nhận hai kiểu giá trị. Tên trường là image_url, nhưng url không bắt buộc là link web:
- Link web (
https://...): máy chủ của nhà cung cấp tự tải ảnh về. Ảnh phải công khai. - Data URL: một “địa chỉ” chứa luôn dữ liệu của ảnh, dạng
data:<kiểu MIME>;base64,<dữ liệu>. Ví dụdata:image/png;base64,iVBORw0KGgo.... Kiểu MIME (image/png,image/jpeg…) phải khớp định dạng thật của tệp.
Theo tài liệu của OpenAI, Gemini, Groq và Ollama (kiểm tra 10/2026), cả bốn nơi đều nhận data URL base64, còn Ollama không nhận link web. Vì vậy code của bài dùng data URL: đó là cách chạy được ở nhiều nơi nhất.
Base64 làm chuỗi dài thêm khoảng một phần ba. Base64 là cách viết dữ liệu nhị phân bằng 64 ký tự an toàn cho văn bản (A–Z, a–z, 0–9, +, /). Mỗi ký tự mang 6 bit. Ba byte là 24 bit, vừa đúng bốn ký tự. Nhóm cuối thiếu byte thì được đệm bằng dấu = cho đủ bốn ký tự. Nên một tệp byte thành chuỗi dài:
ký tự, trong đó là làm tròn lên. Khi lớn, tỉ lệ này gần : một ảnh 3 MB thành chuỗi khoảng 4 MB trong yêu cầu gửi đi. Ảnh lớn nên thu nhỏ trước khi gửi. Mỗi nhà cung cấp còn giới hạn kích thước và số ảnh trong một yêu cầu, mỗi nơi một khác, nên hãy xem tài liệu của nơi bạn dùng.
Ảnh cũng tốn token. Mô hình không đọc chuỗi base64 như đọc chữ. Nhà cung cấp giải mã ảnh, rồi biến nó thành một chuỗi token ảnh cho mô hình. Ảnh càng lớn, càng chi tiết thì càng nhiều token, và bạn trả tiền cho số token đó. Riêng OpenAI có thêm trường tùy chọn detail trong image_url ("low", "high", "auto"…; giá trị được phép tùy mô hình): "low" rẻ hơn, đủ khi chỉ cần ý chung của ảnh. Vì sao mô hình “nhìn” được ảnh là chuyện của bài Multimodal.
Mô hình phải nhìn được ảnh. Không phải mô hình chat nào cũng nhận ảnh. Gửi ảnh cho mô hình chỉ đọc chữ thì bạn nhận lỗi 400, hoặc tệ hơn, một câu trả lời bịa. Biến LLM_MODEL của bài này phải là một mô hình có hỗ trợ ảnh (vision) ở nhà cung cấp bạn dùng.
Sinh ảnh với images.generate
Phần tiêu đề “Sinh ảnh với images.generate”Sinh ảnh dùng một endpoint riêng, không qua chat:
response = client.images.generate( model=IMAGE_MODEL, prompt=prompt, size="1024x1024", n=1,)model: mô hình sinh ảnh. Nó khác mô hình chat, nên code đọc tên từ một biến riêng làIMAGE_MODEL, theo quy ước<KHẢ_NĂNG>_MODELcủa phần này.prompt: mô tả bức ảnh bạn muốn. Cách viết prompt tốt là chủ đề của bài Prompt Engineering.size: kích thước, ví dụ"1024x1024".n: số ảnh muốn nhận.
Kết quả nằm trong response.data, mỗi phần tử là một ảnh. Ảnh thường về dưới dạng b64_json: chuỗi base64, giải mã bằng base64.b64decode là ra byte của tệp ảnh. Có nơi trả url thay vào đó: một link tạm, sẽ hết hạn, nên phải tải về sớm. Code an toàn nhất là xem cả hai trường, vì trường không dùng sẽ là None.
Không phải nhà cung cấp nào cũng sinh ảnh. Theo tài liệu kiểm tra 10/2026:
- OpenAI có
images.generate, với nhiều tham số riêng nhưquality,output_format,background. Với các mô hình ảnh GPT, ảnh trả về dạng base64. - Gemini (qua lớp tương thích OpenAI) có
images.generate, nhưng chỉ nhậnprompt,model,n,size,response_format. Tham số khác bị bỏ qua im lặng, không báo lỗi. Tham số riêng của Gemini, như tỉ lệ khung hình, đi quaextra_body. - Groq và Ollama: trang tương thích OpenAI của hai nơi này không có endpoint sinh ảnh (10/2026), nên ô sinh ảnh chưa chạy được qua đó. (Ollama có sinh ảnh thử nghiệm qua dòng lệnh, ngoài lớp tương thích OpenAI; xem bài viết của Ollama.)
Bảng nhà cung cấp và OPENAI_BASE_URL của từng nơi nằm ở bài Sử dụng API văn bản. Có thể bạn phải dùng một nhà cung cấp cho phần đọc ảnh và một nhà khác cho phần sinh ảnh.
Video: một tác vụ bất đồng bộ
Phần tiêu đề “Video: một tác vụ bất đồng bộ”Dựng một đoạn video có thể mất vài phút. Vì vậy API video không trả video ngay trong lần gọi. Nó theo khuôn tác vụ bất đồng bộ: gửi rồi chờ kết quả sau.
- Tạo job. Bạn gửi prompt. API trả về ngay một
idvà trạng thái, thường làqueued(đang xếp hàng). - Chờ. Trạng thái chuyển qua
in_progressrồi tớicompletedhoặcfailed. Bạn biết điều đó bằng một trong hai cách:- Polling: hỏi lại trạng thái theo chu kỳ.
- Webhook: bạn đăng ký một địa chỉ web, nhà cung cấp tự gọi tới đó khi job xong. Bạn không phải hỏi, nhưng cần một máy chủ nhận được lời gọi từ bên ngoài.
- Lấy kết quả. Job xong thì tải file về và chép vào kho lưu trữ của bạn ngay, vì link tải thường chỉ sống ngắn hạn.
Polling viết bằng giả mã (không gắn với nhà cung cấp nào) trông như sau:
job = tạo_job(prompt) # trả về ngay: job.id, job.status = "queued"chờ = 10 giâylặp khi job.status chưa là "completed" hay "failed": nếu đã quá thời hạn tối đa: báo hết giờ, dừng ngủ(chờ) job = hỏi_trạng_thái(job.id) chờ = min(chờ × 2, 60 giây) # backoff: hỏi thưa dầnnếu job.status = "failed": báo lỗi, dừngtải_về(job.id) rồi lưu vào kho của bạn ngayBa chi tiết đáng nhớ. Chờ thưa dần (backoff), giống cách retry ở bài trước, vì hỏi dồn dập chỉ tốn lượt gọi và dễ gặp lỗi 429. Luôn có thời hạn tối đa, để chương trình không chờ mãi một job bị kẹt. Và tải kết quả về ngay. Lấy ví dụ, tài liệu của API video OpenAI (API nay đã ngừng) gợi ý hỏi mỗi 10–20 giây, có backoff, hoặc dùng webhook; link tải chỉ sống tối đa một giờ.
Kiểm duyệt, bản quyền và nguồn gốc ảnh
Phần tiêu đề “Kiểm duyệt, bản quyền và nguồn gốc ảnh”Kiểm duyệt nội dung. Các nhà cung cấp lọc cả prompt lẫn ảnh sinh ra. Ở OpenAI, yêu cầu bị chặn trả lỗi 400 với mã moderation_blocked, và tài liệu khuyên không thử lại khi chưa sửa prompt: gửi lại y nguyên thì kết quả vẫn vậy. SDK cũng không tự thử lại lỗi 400, nên code của bài bắt openai.BadRequestError và in mã lỗi. Bạn cũng có thể phải xác minh tổ chức trước khi dùng các mô hình GPT Image của OpenAI.
Bản quyền và quyền hình ảnh. Ai sở hữu ảnh do AI tạo, và dùng nó vào việc gì thì được, phụ thuộc điều khoản dịch vụ của từng nhà cung cấp và luật của từng nước. Bài này không phải lời khuyên pháp lý. Vài thói quen an toàn:
- Đọc điều khoản dịch vụ của nhà cung cấp trước khi dùng ảnh vào việc thương mại, và hỏi người có chuyên môn khi cần.
- Không đưa vào prompt hay ảnh đầu vào những thứ bạn không có quyền dùng: ảnh có bản quyền, mặt người thật chưa xin phép, nhãn hiệu.
- Khi công bố, ghi rõ ảnh hay video do AI tạo.
Nguồn gốc nội dung (content provenance) trả lời câu hỏi “tấm ảnh này từ đâu ra?”. Có hai cách đánh dấu chính:
- C2PA (Coalition for Content Provenance and Authenticity) là một chuẩn mở, gọi là Content Credentials: gắn vào tệp một tờ khai lịch sử, ghi ảnh được tạo và sửa bằng công cụ nào. Tờ khai nằm trong metadata (thông tin kèm theo tệp), nên dễ rơi mất khi chụp màn hình, cắt ghép, hay đăng lên mạng xã hội.
- Watermark vô hình: một dấu in chìm ngay trong điểm ảnh. Nó khó xóa hơn metadata nhưng không tuyệt đối: chỉnh sửa mạnh vẫn có thể phá được. Ví dụ, Google ghi rằng mọi ảnh sinh ra bằng Gemini đều mang watermark SynthID.
Hai điều suy ra: không thấy dấu không chứng minh ảnh là thật, và có dấu chỉ nói ảnh được làm bằng công cụ nào, không bảo đảm nội dung đúng sự thật.
Giới hạn
Phần tiêu đề “Giới hạn”- Tham số và định dạng khác nhau giữa các nhà cung cấp. Phần chung là
messagescó ảnh, vàimages.generatevới vài tham số cơ bản. Mọi thứ khác phải đọc tài liệu từng nơi (hộp thứ ba ở mục Lỗi hay gặp). - Mô hình đọc ảnh vẫn có thể sai: đọc nhầm số trên hóa đơn, đếm sai đồ vật. Việc quan trọng thì kiểm lại kết quả.
Minh họa
Phần tiêu đề “Minh họa”Bảng đầu là hội thoại mà ô code “Hỏi mô hình về một tấm ảnh” gửi đi. Hãy nhìn vào lượt user: content của nó là một danh sách hai phần, không còn là một chuỗi như ở bài trước.
| Vai trò | Nội dung |
|---|---|
system | Chuỗi: “Bạn trả lời ngắn gọn bằng tiếng Việt.” |
user | Danh sách hai phần. Phần 1, text: “Ảnh có những hình gì, màu gì, nằm ở đâu?”. Phần 2, image_url: data:image/png;base64,iVBORw0KGgo…, dài 22 ký tự tiền tố cộng 160 ký tự base64 của ảnh thử 118 byte |
assistant | Một chuỗi chữ: câu trả lời của mô hình. Mô hình đọc ảnh nhưng chỉ trả lời bằng chữ |
Bảng thứ hai đặt ba luồng của bài cạnh nhau. Nhìn vào hai hàng “Gọi gì” và “Thời gian”: đó là chỗ ba luồng khác nhau nhiều nhất.
| Tiêu chí | Hiểu ảnh | Sinh ảnh | Video |
|---|---|---|---|
| Gọi gì | chat.completions.create | images.generate | API video riêng của từng nhà (không có qua SDK openai, 10/2026) |
| Gửi đi | messages, ảnh là một phần của content | prompt, size, n | prompt, có khi kèm ảnh đầu vào |
| Nhận về | Chữ | Ảnh (b64_json hoặc url) | Một id và trạng thái; file video tải sau |
| Thời gian | Như một lần chat | Thường lâu hơn chat, tùy mô hình và chất lượng | Vài phút; phải polling hoặc chờ webhook |
| Mô hình | LLM_MODEL (phải nhìn được ảnh) | IMAGE_MODEL | Mô hình video |
Ví dụ code
Phần tiêu đề “Ví dụ code”Code trong bài viết và kiểm tra lần cuối tháng 10/2026, với Python 3.14 và openai 3.37. Ô thứ nhất chạy ngay trên trang, vì nó chỉ dùng thư viện chuẩn của Python. Hai ô sau gọi API, nên bạn chạy trên máy mình. Cách đặt biến môi trường cho bash và PowerShell có ở mục Chuẩn bị: nhà cung cấp và biến môi trường của bài Sử dụng API văn bản; ô sinh ảnh cần thêm biến IMAGE_MODEL, đặt giống hệt LLM_MODEL.
Từ byte ảnh tới data URL
Phần tiêu đề “Từ byte ảnh tới data URL”Ô này tự vẽ một ảnh PNG nhỏ 48 × 48 điểm (nền trắng, hình vuông đỏ ở giữa) bằng thư viện chuẩn, rồi mã hóa base64 và ghép thành data URL, đúng như khi gửi ảnh cho API.
Từ byte ảnh tới data URL
# Biến byte của một ảnh PNG thành data URL base64, như khi gửi ảnh cho API.import base64import structimport zlib
def demo_png(size): # Ảnh thử: nền trắng, hình vuông đỏ ở giữa. Chỉ dùng thư viện chuẩn. a, b = size // 4, 3 * size // 4 raw = b"".join( b"\x00" + b"".join( # mỗi hàng PNG mở đầu bằng 1 byte bộ lọc b"\xff\x00\x00" if a <= x < b and a <= y < b else b"\xff" * 3 for x in range(size)) for y in range(size))
def chunk(kind, data): crc = struct.pack(">I", zlib.crc32(kind + data)) return struct.pack(">I", len(data)) + kind + data + crc
ihdr = struct.pack(">IIBBBBB", size, size, 8, 2, 0, 0, 0) return (b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", ihdr) + chunk(b"IDAT", zlib.compress(raw, 9)) + chunk(b"IEND", b""))
png = demo_png(48)b64 = base64.b64encode(png).decode("ascii") # 3 byte -> 4 ký tựdata_url = f"data:image/png;base64,{b64}"
print(f"PNG bytes: {len(png)}")print(f"base64 chars: {len(b64)}")print(f"ratio: {len(b64) / len(png):.3f}")print(f"data URL start: {data_url[:40]}...")
# Giải mã ngược phải ra đúng byte ban đầuprint("round trip ok: ", base64.b64decode(b64) == png)The first run downloads Python, about 10 MB.
Ảnh thử nặng 118 byte, chuỗi base64 dài 160 ký tự, đúng công thức . Tỉ lệ 1.356 hơi lớn hơn vì 118 không chia hết cho 3: , nên nhóm cuối chỉ có 1 byte và được đệm thêm hai dấu = cho đủ bốn ký tự. Data URL mở đầu bằng data:image/png;base64, rồi tới iVBORw0KGgo: chuỗi này mã hóa 8 byte chữ ký mà tệp PNG nào cũng mở đầu bằng. Dòng cuối kiểm tra giải mã ngược ra đúng byte ban đầu.
Nếu chạy ô này bằng Python trên máy, số byte có thể lệch vài byte, vì bản thư viện nén zlib mỗi nơi một khác; công thức thì vẫn đúng.
Hỏi mô hình về một tấm ảnh
Phần tiêu đề “Hỏi mô hình về một tấm ảnh”Ô này dùng lại ảnh thử ở trên (tạo tệp anh-thu.png nếu chưa có), ghép data URL với kiểu MIME đoán từ đuôi tệp, rồi hỏi mô hình. Đổi IMAGE_PATH thành đường dẫn tới ảnh của bạn để hỏi về ảnh thật; mimetypes.guess_type sẽ đổi tiền tố thành image/jpeg khi tệp là .jpg. Với đuôi tệp lạ, hàm này trả None, và tiền tố thành data:None;base64,: khi đó hãy ghi kiểu MIME bằng tay.
Run on your machine
Hỏi mô hình về một tấm ảnh
- Install
pip install openai- Environment variables
OPENAI_BASE_URL(optional),OPENAI_API_KEY,LLM_MODEL
# Hỏi một mô hình vision về một ảnh, gửi ảnh dạng data URL base64.import base64import mimetypesimport osimport structimport zlib
from openai import OpenAI
def demo_png(size): # Ảnh thử: nền trắng, hình vuông đỏ ở giữa (giống ô chạy trên trang) a, b = size // 4, 3 * size // 4 raw = b"".join( b"\x00" + b"".join( b"\xff\x00\x00" if a <= x < b and a <= y < b else b"\xff" * 3 for x in range(size)) for y in range(size))
def chunk(kind, data): crc = struct.pack(">I", zlib.crc32(kind + data)) return struct.pack(">I", len(data)) + kind + data + crc
ihdr = struct.pack(">IIBBBBB", size, size, 8, 2, 0, 0, 0) return (b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", ihdr) + chunk(b"IDAT", zlib.compress(raw, 9)) + chunk(b"IEND", b""))
IMAGE_PATH = "anh-thu.png" # đổi thành đường dẫn tới ảnh của bạnif not os.path.exists(IMAGE_PATH): with open(IMAGE_PATH, "wb") as f: f.write(demo_png(48))
with open(IMAGE_PATH, "rb") as f: b64 = base64.b64encode(f.read()).decode("ascii")mime = mimetypes.guess_type(IMAGE_PATH)[0] # "image/png", "image/jpeg"...data_url = f"data:{mime};base64,{b64}"
client = OpenAI( base_url=os.environ.get("OPENAI_BASE_URL"), # bỏ trống: dùng OpenAI api_key=os.environ["OPENAI_API_KEY"],)MODEL = os.environ["LLM_MODEL"] # phải là mô hình nhìn được ảnh
response = client.chat.completions.create( model=MODEL, messages=[ {"role": "system", "content": "Bạn trả lời ngắn gọn bằng tiếng Việt."}, {"role": "user", "content": [ # content là danh sách các phần {"type": "text", "text": "Ảnh có những hình gì, màu gì, nằm ở đâu?"}, {"type": "image_url", "image_url": {"url": data_url}}, ]}, ],)print(response.choices[0].message.content)Phần gọi API giống hệt bài trước, trừ content của lượt user là danh sách hai phần. Bạn nhận về một đoạn chữ mô tả ảnh; mỗi lần chạy, câu chữ một khác. Nếu nhận lỗi 400 nói mô hình không hỗ trợ ảnh, hãy đổi LLM_MODEL sang một mô hình vision của nhà cung cấp bạn dùng.
Sinh ảnh từ prompt
Phần tiêu đề “Sinh ảnh từ prompt”Ô này xin một bức tranh màu nước từ prompt, rồi lưu ra tệp anh-sinh-ra.png.
Run on your machine
Sinh ảnh từ prompt
- Install
pip install openai- Environment variables
OPENAI_BASE_URL(optional),OPENAI_API_KEY,IMAGE_MODEL
# Sinh một ảnh từ prompt bằng images.generate, rồi lưu ra tệp.import base64import os
import openaifrom openai import OpenAI
client = OpenAI( base_url=os.environ.get("OPENAI_BASE_URL"), # bỏ trống: dùng OpenAI api_key=os.environ["OPENAI_API_KEY"],)IMAGE_MODEL = os.environ["IMAGE_MODEL"] # mô hình sinh ảnh, khác LLM_MODEL
prompt = ( "Tranh màu nước: một chiếc xe đạp dựng cạnh quán cà phê vỉa hè " "ở Hà Nội, buổi sáng, nắng dịu.")try: response = client.images.generate( model=IMAGE_MODEL, prompt=prompt, size="1024x1024", n=1, )except openai.BadRequestError as err: # Bị kiểm duyệt chặn, hoặc tham số không hợp với mô hình. # Gửi lại y nguyên thì kết quả vẫn vậy: hãy sửa prompt. print("Yêu cầu bị từ chối:", err.code or err.message) raise SystemExit(1)
image = response.data[0]if image.b64_json: # ảnh trả về dạng chuỗi base64 with open("anh-sinh-ra.png", "wb") as f: f.write(base64.b64decode(image.b64_json)) print("Đã lưu anh-sinh-ra.png")else: # vài nơi trả URL tạm: tải về ngay, URL sẽ hết hạn print("URL của ảnh:", image.url)Khi thành công, ô in tên tệp đã lưu. Nếu nhà cung cấp trả url thay cho b64_json, ô in link để bạn tải về ngay. Nếu yêu cầu bị từ chối, ô in mã lỗi (ví dụ moderation_blocked ở OpenAI) hoặc thông báo lỗi, rồi dừng. Trường hợp này hãy sửa prompt, đừng chạy lại y nguyên. Theo tài liệu, ô dùng được với OpenAI, và với Gemini qua lớp tương thích (ví dụ trong tài liệu của Gemini truyền thêm response_format="b64_json"). Với Groq hay Ollama thì chưa, vì trang tương thích OpenAI của hai nơi này không có endpoint sinh ảnh (10/2026).
Lỗi hay gặp
Phần tiêu đề “Lỗi hay gặp”Kiểm tra nhanh
Phần tiêu đề “Kiểm tra nhanh”Tóm tắt và đọc thêm
Phần tiêu đề “Tóm tắt và đọc thêm”Ý chính:
- Hỏi về ảnh vẫn là chat:
contentcủa lượtuserlà danh sách các phầntextvàimage_url.urlnhận link web hoặc data URLdata:<MIME>;base64,...; data URL chạy được ở nhiều nhà cung cấp nhất. Base64 dài khoảng tệp gốc, và ảnh còn tốn token. - Sinh ảnh đi qua cửa riêng
images.generate, mô hình đọc từIMAGE_MODEL. Kết quả ởresponse.data[0]: đọcb64_json, giải mã rồi lưu tệp; xem cảurlphòng khi nhà cung cấp trả link tạm. Không phải nơi nào cũng sinh ảnh, và tham số khác nhau giữa các nơi. - Video là tác vụ bất đồng bộ: tạo job, giữ
id, polling có backoff và thời hạn (hoặc webhook), tải kết quả về ngay. API video đổi rất nhanh (10/2026), nên bài chỉ dạy khuôn này. - Lỗi kiểm duyệt không tự hết khi gửi lại. Dùng ảnh AI thì đọc điều khoản dịch vụ và ghi rõ là ảnh AI. C2PA và watermark cho biết nguồn gốc, nhưng thiếu chúng không chứng minh ảnh thật, có chúng không chứng minh nội dung đúng.
Đọc thêm:
- OpenAI (2026). Images and vision và Image generation. Cách đưa ảnh vào yêu cầu, trường
detail, giới hạn định dạng; tham số củaimages.generatevà các lỗi kiểm duyệt. Ví dụ trên trang dùng Responses API, khác Chat Completions của bài này ở cú pháp. - Google (2026). OpenAI compatibility, các mục về ảnh. Ảnh đi vào,
images.generatequa lớp tương thích, danh sách tham số được nhận và cách dùngextra_body. - Google (2026). Image generation. Sinh và sửa ảnh bằng Gemini qua API riêng của Google; trang ghi rằng mọi ảnh sinh ra đều mang watermark SynthID.
- Groq (2026). Images and Vision. Gửi ảnh cho mô hình vision của Groq bằng link web hoặc data URL base64.
- Ollama (2026). OpenAI compatibility. Những gì endpoint kiểu OpenAI của Ollama hỗ trợ, gồm ảnh đi vào dạng base64.
- C2PA (2026). Coalition for Content Provenance and Authenticity. Trang của chuẩn Content Credentials: chuẩn này dùng để làm gì.
- OpenAI (2026). Video generation with Sora. API đã ngừng ngày 24/9/2026, nhưng trang vẫn là một ví dụ rõ về job bất đồng bộ: các trạng thái, polling, webhook, thời hạn của link tải.
Your browser is blocking storage. Your progress will be lost when you reload the page.
Content licensed under CC BY-NC-SA 4.0. Code under the MIT license.About