AI Hình Ảnh
API & tự động hoá hình ảnh

Tạo hàng loạt hình ảnh sản phẩm từ bảng tính CSV, có trần chi phí điểm

03/10/2026 · 8 phút đọc · AI Hình Ảnh

Một đoạn mã Python đọc bảng tính sản phẩm, tính trước tổng điểm, chạy thử năm dòng, đặt trần chi phí, chạy tiếp được khi đứt giữa chừng và ghi lại kết quả từng dòng.

Tạo hàng loạt hình ảnh sản phẩm từ bảng tính CSV, có trần chi phí điểm

Một gian hàng gốm trên Shopee có 240 mã sản phẩm, mỗi mã cần thêm hai hình ảnh bối cảnh: chén đĩa trên bàn ăn gia đình, bình hoa trên kệ gỗ. Ngồi gõ 480 lần trên trang web thì không ai làm nổi. Bảng tính sản phẩm thì có sẵn. Bài này biến bảng tính đó thành hình ảnh bằng một đoạn mã Python, với ba thứ mà người chủ gian hàng quan tâm hơn cả: biết trước tốn bao nhiêu điểm, không bao giờ vượt trần, và đứt giữa chừng thì chạy tiếp, không tốn lại.

Hình ảnh bối cảnh làm bằng AI chỉ nên là hình phụ. Hình chính của sản phẩm trên sàn nên là hình chụp thật để khách nhận đúng món mình thấy. Lý do ở bài hình ảnh AI trong quảng cáo.

Bước 1: chuẩn bị bảng tính

Xuất từ Google Sheets hay Excel ra CSV, mã hoá UTF-8. Các cột:

CộtÝ nghĩaVí dụ
maMã sản phẩm, dùng đặt tên tệp, chỉ chữ không dấu, số, gạch ngangBT-CHEN-05
canhCâu lệnh vẽ tiếng Anh tả cảnhxem dưới
hangplus, pro hoặc max; để trống là plusplus
kho3:2, 1:1, 2:3, 16:9, 9:16, 4:5; trống là 1:11:1
soSố hình ảnh cho dòng này, 1–4; trống là 12

Cột canh phải là tiếng Anh vì API không tự dịch. Cách viết nhanh cho cả trăm dòng: viết một khuôn cho mỗi nhóm hàng, chỉ thay phần đồ vật.

Khuôn nhóm chén bát: Set of handmade ceramic {đồ vật} on a rustic wooden dining table, Vietnamese home kitchen, morning window light, steam from a bowl of rice, no text, no logo, realistic product photo
Dòng cụ thể: Set of handmade ceramic rice bowls with blue glaze on a rustic wooden dining table, ...

Khuôn tốt thì hình ảnh cả bộ đồng đều về ánh sáng và màu, gian hàng trông chuyên nghiệp. Để tìm khuôn, thử vài mô tả tiếng Việt trên ô vẽ, xem dòng "Câu lệnh vẽ" mà AI dịch ra, giữ lại câu nào cho kết quả ưng nhất.

Bảng mẫu san_pham.csv:

```csv
ma,canh,hang,kho,so
BT-CHEN-05,"Set of handmade ceramic rice bowls with blue glaze on a rustic wooden dining table, Vietnamese home kitchen, morning window light, no text, no logo, realistic product photo",plus,1:1,2
BT-BINH-12,"Tall crackle-glaze ceramic vase with fresh lotus flowers on a dark wooden shelf, soft side light, calm living room, no text, no logo, realistic product photo",pro,4:5,1
```

Bước 2: đoạn mã

```python
#!/usr/bin/env python3
"""Tạo hình ảnh sản phẩm hàng loạt từ CSV qua API AI Hình Ảnh.
python3 ve_csv.py san_pham.csv --tran 150000 # chạy thật
python3 ve_csv.py san_pham.csv --tinh # chỉ tính điểm
python3 ve_csv.py san_pham.csv --thu 5 --tran 10000 # chạy thử 5 dòng
"""
import argparse, base64, csv, os, random, sys, time
from pathlib import Path
import requests

API = "https://aihinhanh.com/v1"
KEY = os.environ.get("AHN_KEY", "") # ahn_XXXX
KHO = {"3:2": "1536x1024", "1:1": "1280x1280", "2:3": "1024x1536",
"16:9": "1664x928", "9:16": "928x1664", "4:5": "1152x1440"}
RA = Path("hinh_anh_ra")

def bang_gia() -> dict:
r = requests.get(f"{API}/models", timeout=30)
r.raise_for_status()
return {m["id"]: m["price_vnd"] for m in r.json()["data"] if "price_vnd" in m}

def doc_csv(tep: str) -> list:
dong = []
with open(tep, encoding="utf-8-sig", newline="") as f:
for i, d in enumerate(csv.DictReader(f), start=2):
ma, canh = (d.get("ma") or "").strip(), (d.get("canh") or "").strip()
if not ma or not canh:
print(f"Dòng {i}: thiếu mã hoặc cảnh, bỏ qua")
continue
dong.append({"ma": ma, "canh": canh,
"hang": (d.get("hang") or "plus").strip().lower(),
"size": KHO.get((d.get("kho") or "1:1").strip(), "1280x1280"),
"so": max(1, min(4, int(d.get("so") or 1)))})
return dong

def con_thieu(d: dict) -> int:
"""Số hình ảnh của dòng chưa có tệp trên đĩa (để chạy tiếp)."""
co = sum(1 for k in range(1, d["so"] + 1) if (RA / f"{d['ma']}-{k}.webp").exists())
return d["so"] - co

def ve(d: dict, n: int) -> dict:
payload = {"model": d["hang"], "prompt": d["canh"], "size": d["size"],
"n": n, "output_format": "webp"}
for lan in range(5):
r = requests.post(f"{API}/images/generations", json=payload, timeout=120,
headers={"Authorization": f"Bearer {KEY}"})
if r.status_code == 200:
return r.json()
if r.status_code in (400, 401, 402):
raise SystemExit(f"{d['ma']}: lỗi {r.status_code} {r.text[:200]}")
cho = int(r.headers.get("Retry-After", "30")) + random.uniform(0, 5)
print(f" {d['ma']}: máy bận ({r.status_code}), chờ {cho:.0f}s")
time.sleep(cho)
return {"data": [], "usage": {"credits": 0}}

def main():
ap = argparse.ArgumentParser()
ap.add_argument("csv")
ap.add_argument("--tran", type=int, default=0, help="trần điểm cho lần chạy này")
ap.add_argument("--tinh", action="store_true", help="chỉ tính điểm, không vẽ")
ap.add_argument("--thu", type=int, default=0, help="chỉ chạy N dòng đầu")
a = ap.parse_args()

gia = bang_gia()
dong = doc_csv(a.csv)
if a.thu:
dong = dong[: a.thu]
for d in dong:
if d["hang"] not in gia:
sys.exit(f"{d['ma']}: hạng '{d['hang']}' không có, chỉ dùng {list(gia)}")

viec = [(d, con_thieu(d)) for d in dong if con_thieu(d) > 0]
tong = sum(gia[d["hang"]] * n for d, n in viec)
so_hinh = sum(n for _, n in viec)
print(f"{len(viec)} dòng, {so_hinh} hình ảnh, ước tính {tong:,} điểm")
if a.tinh:
return
if not KEY or not a.tran:
sys.exit("Cần AHN_KEY và --tran (trần điểm).")

RA.mkdir(exist_ok=True)
da_tieu = 0
with open("ket_qua.csv", "a", encoding="utf-8", newline="") as log:
w = csv.writer(log)
for d, n in viec:
du_kien = gia[d["hang"]] * n
if da_tieu + du_kien > a.tran:
print(f"Dừng trước {d['ma']}: sẽ vượt trần {a.tran:,} điểm")
break
kq = ve(d, n)
co = sum(1 for k in range(1, d["so"] + 1) if (RA / f"{d['ma']}-{k}.webp").exists())
for i, x in enumerate(kq["data"], start=co + 1):
(RA / f"{d['ma']}-{i}.webp").write_bytes(base64.b64decode(x["b64_json"]))
da_tieu += kq["usage"]["credits"]
w.writerow([time.strftime("%Y-%m-%d %H:%M"), d["ma"], d["hang"],
len(kq["data"]), n, kq["usage"]["credits"]])
log.flush()
print(f"{d['ma']}: {len(kq['data'])}/{n} hình ảnh, cộng dồn {da_tieu:,} điểm")
print(f"Xong lần chạy, đã tiêu {da_tieu:,} điểm")

if __name__ == "__main__":
main()
```

Bước 3: chạy theo ba nhịp

Nhịp 1: tính điểm

```bash
python3 ve_csv.py san_pham.csv --tinh
```

Đoạn mã lấy bảng giá hiện hành từ GET /v1/models (không ghi cứng giá trong mã), đếm số hình ảnh còn thiếu và in tổng điểm. Với ví dụ gian hàng gốm:

NhómSố mãHạngHình ảnh mỗi mãĐiểm
Chén, bát, đĩa160Plus (500)2160.000
Bình hoa, chậu60Pro (1.000)160.000
Bộ ấm trà có người rót20Max (1.500)130.000
Cộng240400250.000

Nhóm "có người rót trà" lên Max vì bàn tay cầm ấm là chỗ hạng Plus hay sai (ngón thừa, ngón dính). Chén bát không có người thì Plus là đủ đẹp và nhanh nhất.

Nhịp 2: chạy thử năm dòng

```bash
export AHN_KEY="ahn_XXXX"
python3 ve_csv.py san_pham.csv --thu 5 --tran 10000
```

Mở thư mục hinh_anh_ra, xem từng hình ảnh thật kỹ: màu men có đúng không, có chữ lạ trên chén không, ánh sáng có đồng đều không. Năm dòng tốn vài nghìn điểm; sửa khuôn câu lệnh ở bước này rẻ hơn rất nhiều so với phát hiện sau khi đã vẽ 400 hình ảnh.

Nhịp 3: chạy thật có trần

```bash
python3 ve_csv.py san_pham.csv --tran 260000
```

Trần đặt hơi cao hơn ước tính một chút. Đoạn mã kiểm trước mỗi dòng: nếu vẽ dòng này mà vượt trần thì dừng. Trần là trần của lần chạy, không phải số dư ví; ví hết điểm thì API trả 402 và đoạn mã cũng dừng.

Chạy tiếp khi đứt giữa chừng

Tên tệp là ma-1.webp, ma-2.webp… Trước khi vẽ, đoạn mã đếm xem mỗi mã còn thiếu bao nhiêu tệp và chỉ gửi đúng số đó. Vì vậy:

  • Mất điện ở dòng 137: chạy lại đúng lệnh cũ, 136 dòng đầu được bỏ qua, không tốn thêm điểm.
  • Một dòng xin 2 hình ảnh mà máy chỉ kịp trả 1 (phần thiếu đã được hoàn điểm): lần chạy sau tự vẽ bù đúng 1.
  • Muốn vẽ lại một mã vì không ưng: xoá tệp của mã đó, chạy lại.

Tệp ket_qua.csv ghi từng dòng: thời điểm, mã, hạng, số hình ảnh nhận, số xin, điểm thật. Cộng cột cuối là ra chi phí thật, đối chiếu được với lịch sử ví.

Những lỗi hay gặp với bảng tính thật

Triệu chứngNguyên nhânSửa
Chữ có dấu thành ký tự lạCSV xuất từ Excel bằng mã hoá khác UTF-8Xuất lại bằng "CSV UTF-8"; mã đã đọc utf-8-sig để xử lý ký tự BOM
Dòng bị bỏ qua "thiếu cảnh"Ô canh có dấu phẩy mà không bọc nháy képĐể bảng tính tự xuất, đừng sửa CSV bằng tay trong trình soạn thảo
Hình ảnh của cả bộ lệch màu nhauMỗi dòng viết câu lệnh kiểu khácDùng chung một khuôn câu cho mỗi nhóm hàng
Tên tệp lộn xộn, ghi đè nhauMã sản phẩm trùng hoặc có dấu cáchLàm sạch cột ma trước khi chạy
Chạy rất chậm vào buổi tốiMáy vẽ đang bận việc khácChạy qua đêm, hoặc chia đợt

Ước thời gian

Plus khoảng 6–10 giây mỗi hình ảnh, Pro 20–25 giây, Max 25–40 giây, chưa tính lúc máy bận. Đợt 400 hình ảnh ở ví dụ trên chạy tuần tự mất khoảng hai đến ba giờ khi máy rảnh. Cho chạy từ tối, sáng ra kiểm hình ảnh. Đoạn mã chạy tuần tự có chủ ý; giải thích vì sao không nên chạy song song ở bài xử lý lỗi 503 và hàng đợi.

Sau khi có hình ảnh

Tệp webp ra thẳng từ API đã nhẹ, nhưng mỗi sàn có yêu cầu khổ, dung lượng riêng. Cách đổi cỡ, đặt tên cho dễ tìm và viết thẻ alt có ở bài lưu tệp, đặt tên, nén webp, thẻ alt. Tạo khoá ở trang khoá API.

Hỏi đáp nhanh

Có cách nào biết trước tổng chi phí không?
Có. Chạy đoạn mã với tuỳ chọn --tinh, nó lấy bảng giá hiện hành từ /v1/models và cộng điểm theo hạng, số hình ảnh của từng dòng mà không vẽ gì.
Trần điểm khác gì số dư ví?
Trần là giới hạn bạn tự đặt cho một lần chạy; đoạn mã dừng trước dòng nào sẽ làm vượt trần. Số dư ví là giới hạn thật của tài khoản, hết điểm thì API trả lỗi 402 và đoạn mã cũng dừng.
Đứt mạng giữa chừng có tốn điểm vẽ lại không?
Không, với những dòng đã có tệp. Đoạn mã đếm tệp đã có của từng mã và chỉ vẽ phần còn thiếu, nên chạy lại cùng lệnh là đi tiếp đúng chỗ.
Viết cột cảnh bằng tiếng Việt được không?
Vẫn vẽ được nhưng kém sát ý, vì API không tự dịch. Nên viết một khuôn câu tiếng Anh cho mỗi nhóm hàng rồi chỉ thay tên đồ vật.
Có nên dùng hình ảnh AI làm hình chính sản phẩm trên sàn không?
Không nên. Hình chính nên là hình chụp sản phẩm thật để khách nhận đúng hàng; hình ảnh AI hợp làm hình bối cảnh, hình phụ, hình khổ ngang đầu gian hàng.
Tạo hình ảnh bằng AI từ mô tả tiếng ViệtGõ mô tả tiếng Việt, chọn hạng Plus, Pro hoặc Max — có hình ảnh trong vài giây.
Vẽ hình ảnh ngay

Đọc tiếp

Liên hệ AI Hình Ảnh
📞 Gọi 0918 832 283💬 Chat Zalo🟢 WhatsAppĐóng