ملی ای‌پی‌آی

ساخت تصویر با API جمینای: از درخواست تا ذخیرهٔ فایل

ساخت تصویر با API همان فراخوان گفت‌وگوست و تصویر در کلید images برمی‌گردد. این راهنما درخواست، گرفتن فایل از پاسخ و ذخیره‌اش را با کد Python و نکتهٔ هزینه می‌گوید.

ساخت تصویر با API همان فراخوان گفت‌وگوست: توصیف تصویر را مثل یک پیام معمولی می‌فرستید و تصویر در کلید images پاسخ برمی‌گردد. آموزش‌های فارسی زیادی برای کار با خود جمینای هست، ولی این راهنما به سطح API می‌پردازد: درخواست، گرفتن فایل از پاسخ و ذخیره‌اش، با مدل Gemini Image.

چهار قدم ساخت تصویر با API: درخواست گفت‌وگو با توصیف تصویر، پاسخ با تصویر در کلید images و content خالی، جداکردن بخش base64 از data URI، و ذخیرهٔ فایل
از درخواست تا ذخیرهٔ تصویر

درخواست

مسیر جدایی برای تصویر نیست. همان نشانی گفت‌وگو، همان بدنه:

curl https://melliapi.net/api/v1/ai/chat/completions/ \
  -H "Authorization: Bearer $MELLIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google-gemini-3-pro-image",
    "max_tokens": 4096,
    "messages": [
      {"role": "user", "content": "یک فنجان قهوه روی میز چوبی، نور طبیعی صبح، نمای نزدیک"}
    ]
  }'

پاسخ: تصویر در images است، نه content

مهم‌ترین نکته همین است. برای مدل تصویرساز، content معمولاً خالی است و این طبیعی است. هر عضو images یک data URI است، یعنی رشته‌ای که با data:image/png;base64, شروع می‌شود و باقی‌اش خود تصویر است. پاسخ ممکن است چند مگابایت باشد.

ذخیرهٔ فایل (Python)

import base64, os, requests

URL = "https://melliapi.net/api/v1/ai/chat/completions/"

def make_image(prompt, name):
    r = requests.post(
        URL,
        headers={"Authorization": "Bearer " + os.environ["MELLIAPI_API_KEY"]},
        json={
            "model": "google-gemini-3-pro-image",
            "max_tokens": 4096,
            "messages": [{"role": "user", "content": prompt}],
        },
        timeout=180,
    )
    data = r.json()
    if not data.get("ok"):
        raise RuntimeError(data["error"]["code"])
    if not data["images"]:
        raise RuntimeError("پاسخ بدون تصویر بود")
    saved = []
    for i, uri in enumerate(data["images"]):
        header, b64 = uri.split(",", 1)
        ext = header.split("/")[1].split(";")[0]
        path = "%s-%d.%s" % (name, i, ext)
        with open(path, "wb") as f:
            f.write(base64.b64decode(b64))
        saved.append(path)
    return saved, data["billing"]["amountRial"]

دو نکته در کد هست:

  • مهلت اتصال بلند: ساخت تصویر زمان می‌برد. سمت خودتان دست‌کم ۱۲۰ ثانیه صبر کنید؛ مهلت کوتاه یعنی پاسخی نمی‌گیرید و هزینهٔ تولیدشده را داده‌اید.
  • بررسی خالی‌بودن images: اگر آرایه خالی بود، خطا بدهید و نه موفقیت. «پاسخ موفق بدون تصویر» بدترین حالتی است که کسی متوجهش نمی‌شود.

دستور تصویر

سه چیز در توصیف مهم است: سوژه با جزئیات دیدنی (نه صفت کلی)، نور و فضا، و قاب (نزدیک، دور، از بالا). «فنجان سرامیکی آبی روی پیشخوان چوبی، نور صبح از سمت چپ، نمای نزدیک» نتیجهٔ قابل پیش‌بینی‌تری می‌دهد تا «یک فنجان قهوهٔ زیبا».

هزینه

قیمت این مدل‌ها توکنی است و ثابت به‌ازای هر تصویر نیست: تصویر خروجی هم به توکن شمرده می‌شود. مبلغ هر فراخوان در billing.amountRial نوشته شده است، پس هزینهٔ چند تصویر آزمایشی را بسنجید و بعد برای ترافیک حساب کنید. هر بار که تصویر را دوباره بسازید، دوباره پول می‌دهید؛ پس دستور را روی چند نمونه بیازمایید و بعد انبوه تولید کنید.

نوشتهٔ فارسی روی تصویر

خط فارسی روی تصویر قابل اتکا نیست؛ حروف ممکن است جدا یا اشتباه شوند. اگر تصویر باید نوشته داشته باشد، تصویر را بدون متن بسازید و متن را خودتان با کد یا ابزار طراحی روی آن بگذارید. جزئیات در صفحهٔ مدل آمده است.

آنچه این روش انجام نمی‌دهد

  • نتیجه را تضمین نمی‌کند. همان دستور دو بار دو تصویر متفاوت می‌دهد.
  • تصویر را برای شما ذخیره نمی‌کند. پاسخ را بگیرید و فایل را همان لحظه نزد خودتان نگه دارید.
  • برای ویدیو نیست. ساخت ویدیو مسیر و رفتار ناهمگام جدایی دارد؛ بخش ویدیوی مستندات را ببینید.
آخرین بازبینی: تیم تحریریه ملی ای‌پی‌آی

پرسش و تجربه کاربران

اگر این راهنما جوابتان را نداد، همین‌جا بپرسید. پرسش‌ها را تیمملی ای‌پی‌آی پاسخ می‌دهد و هر نظر پیش از انتشار بررسی می‌شود.

هنوز پرسشی ثبت نشده، اولین نفر باشید.