واجهة Gemini API لتوليد الصور في Python: مثال برمجي

شرح عملي بلغة Python لواجهة Gemini API لتوليد الصور باستخدام نموذج gemini-3.1-flash-image الحالي وواجهة Interactions API. ولّد أول صورة لك، واضبط نسبة العرض إلى الارتفاع والدقة، وعدّل الصور، وأعد المحاولة عند فشل الاستدعاءات، وقدّر التكلفة الفعلية لكل صورة.

واجهة Gemini API لتوليد الصور في Python: مثال برمجي
Cristian Da Conceicao
مؤسس Picasso IA

تستخدم معظم دروس توليد الصور بواسطة Gemini ما يزال gemini-2.5-flash-image، وتدرج صفحة التسعير لدى Google هذا النموذج على أنه مهجور بتاريخ إيقاف هو 2 أكتوبر 2026. وقد مضى هذا التاريخ، لذا ينبغي اعتبار المقتطفات المبنية عليه معطّلة. تستخدم هذه الصفحة النموذج الحالي، gemini-3.1-flash-image، وواجهة Interactions API التي تقدّمها وثائق Google الرسمية الآن بوصفها الخيار الأول.

ستنتقل من مجلد فارغ إلى سكربت يعمل يولّد صورة، ويتحكم في حجمها، ويعدّل صورة فوتوغرافية موجودة، ويحفظ مخرجات مختلطة من نص وصورة، ويصمد أمام حدود معدل الطلبات. كل مقتطف قصير بما يكفي لنسخه في ملف وتشغيله. تكلّف صورة واحدة بدقة 1K على نموذج Flash القياسي حوالي $0.067، لذا يبقى الاختبار رخيصًا.

ما تحتاجه قبل البرمجة

مطوّرة تكتب الشيفرة على مكتب خشبي بجوار كوب قهوة في ضوء الصباح

ثلاثة أشياء تحول بينك وبين أول صورة لك: تثبيت حديث لـ Python 3، وبيانات اعتماد من Google AI Studio، ومشروع مفعّل فيه الفوترة. وتُظهر صفحة التسعير لدى Google عدم وجود مستوى مجاني لأي من نماذج Gemini لتوليد الصور، لذا من المرجح أن يُرفض أول استدعاء من مشروع غير مفوتر.

تثبيت SDK

حزمة واحدة تتكفّل بكل شيء:

pip install -U google-genai

تحتاج واجهة Interactions API إلى google-genai 2.3.0 أو أحدث، ولهذا يكون العلم -U مهمًا. شغّل pip show google-genai إذا فشل أحد المقتطفات أدناه برسالة خطأ في الخاصية على client.interactions.

اضبط بيانات الاعتماد

أنشئ بيانات اعتماد في Google AI Studio، ثم صدّرها كمتغير بيئة باسم المتغير الموضّح أدناه. تقرأ الحزمة هذا المتغير من تلقاء نفسها، فلا يحتاج سكربتك إلى احتواء السر نفسه.

export GEMINI_API_KEY="paste-your-credential-here"

في Windows PowerShell يكون السطر نفسه $env:GEMINI_API_KEY = "paste-your-credential-here".

💡 لا تلصق بيانات الاعتماد أبدًا في سكربت سيُرفع إلى Git. احتفظ بها في متغير بيئة أو في ملف .env يستثنيه .gitignore أصلًا.

اختر نموذجًا

تسرد Google الآن أربعة نماذج لتوليد الصور. ثلاثة منها حالية، والرابع متقاعد.

معرّف النموذجالأحجامالسعر لكل صورةالأفضل لـ
gemini-3.1-flash-lite-image1K فقطحوالي $0.034المهام الجماعية، الصور المصغّرة
gemini-3.1-flash-image0.5K، 1K، 2K، 4K$0.045، $0.067، $0.101، $0.151الخيار الافتراضي لمعظم السكربتات
gemini-3-pro-image1K، 2K، 4K$0.134 (1K و2K)، $0.24 (4K)الأوامر النصية المعقدة متعددة الأجزاء
gemini-2.5-flash-imageغير متاح$0.039متقاعد، لا تستخدمه

الأسعار مأخوذة من صفحة التسعير لدى Google وقت كتابة هذا المقال. راجعها مرة أخرى قبل أي تشغيل كبير.

كيف تختار؟ ابدأ بـ gemini-3.1-flash-image. فهو النموذج الحالي الوحيد الذي يقدم الأحجام الأربعة جميعها، لذا يخدم مسار شيفرة واحد الصور المصغّرة وملفات الطباعة معًا. انتقل إلى Flash Lite عندما تولّد آلاف الصور الصغيرة ويهمّك كل سنت لكل صورة. واستخدم Pro عندما يتكون الأمر النصي من أجزاء كثيرة، مثل تخطيط ملصق يضم عدة عناصر مُسمّاة، ويواصل نموذج أرخص إسقاط التفاصيل. ولأن النماذج الحالية الثلاثة تشترك في شكل الاستدعاء نفسه، فإن تغيير النموذج لاحقًا يعني تعديل سلسلة نصية واحدة فقط.

ولّد أول صورة لك

امرأة تنظر إلى شاشة تعرض صورة فوتوغرافية حادة لبحيرة جبلية

احفظ هذا الكود باسم first_image.py:

import base64
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.1-flash-image",
    input="A photograph of a bowl of oranges on a linen cloth, soft window light",
)

with open("oranges.png", "wb") as f:
    f.write(base64.b64decode(interaction.output_image.data))

شغّل python first_image.py فيظهر ملف oranges.png بجوار السكربت. هذه هي الدورة الكاملة: أمر نصي يدخل، وسلسلة base64 تخرج، وبايتات تُكتب على القرص.

عندما تولّد أكثر من صورة، يستبدل اسم الملف الثابت نتيجتك السابقة. لذا ابنِ الاسم من طابع زمني، مثل f"image_{int(time.time())}.png"، فيترك كل تشغيل ملفه الخاص. وبعد ذلك يمكنك مقارنة اثني عشر تنويعًا من أمر نصي واحد جنبًا إلى جنب.

ما تفعله كل سطر

  • genai.Client() ينشئ عميلًا ويسحب بيانات الاعتماد من متغير البيئة الذي صدّرته سابقًا، فلا يوجد شيء حساس داخل الملف.
  • client.interactions.create() يرسل الأمر النصي ويعيد كائن Interaction يحمل id، وخطوات المخرجات، واختصارات مثل output_image.
  • interaction.output_image.data يحتوي الصورة كـسلسلة base64. يجب فك ترميزها قبل الكتابة، وإلا فسيكون الملف نصًا لا صورة.

اكتب أوامر نصية تعمل

يستجيب النموذج بأفضل شكل لأوصاف المشاهد، لا لقائمة من الوسوم المتفرقة. فالأمر النصي الذي يُقرأ كقائمة لقطات مصوّر يمنحك تحكمًا أكبر من قائمة صفات.

  1. حدّد العنصر الرئيسي والفعل. "خباز ينثر الدقيق فوق رغيف" أفضل من "مخبز".
  2. صِف الإضاءة. ضوء النافذة، أو سماء غائمة، أو الساعة الذهبية، أو شمس الظهيرة القاسية.
  3. أضِف العدسة والمسافة. "صورة شخصية بعدسة 85mm، وعمق ميدان ضحل" أو "لقطة جوية واسعة بعدسة 24mm".
  4. حدّد ما يُستبعد. جملة قصيرة واحدة، مثل "لا يوجد نص في الصورة".

💡 احتفظ بأوامرك النصية في قائمة Python أو في ملف نصي. عندما تفاجئك نتيجة ما، يمكنك تغيير متغير واحد والمقارنة، وهذا أفضل من إعادة الكتابة من الذاكرة.

تحكّم في الحجم ونسبة العرض إلى الارتفاع

منظر من الأعلى لصور مطبوعة بنسب عريضة وطويلة ومربعة على طاولة من خشب البلوط

يعيش الحجم والشكل داخل قاموس response_format. وهذا يربك كثيرين، لأن الشيفرة القديمة كانت تضع إعدادات الصورة في generation_config.

interaction = client.interactions.create(
    model="gemini-3.1-flash-image",
    input="A wide photograph of a coastal road at dawn, 35mm lens, film grain",
    response_format={
        "type": "image",
        "mime_type": "image/jpeg",
        "aspect_ratio": "16:9",
        "image_size": "2K",
    },
)

with open("coast.jpg", "wb") as f:
    f.write(base64.b64decode(interaction.output_image.data))

بما أن mime_type المطلوب بصيغة JPEG، يحصل الملف على امتداد .jpg. طابق الامتداد مع النوع الذي تطلبه، فلن يشتكي عارض الصور لديك أبدًا.

نسب العرض إلى الارتفاع التي يمكنك طلبها

تسرد وثائق Google عشر نسب: 1:1، 3:2، 2:3، 3:4، 4:3، 4:5، 5:4، 9:16، 16:9، و 21:9.

النسبةالاستخدام المعتاد
1:1الصور الشخصية، بطاقات المنتجات
4:5منشورات الخلاصة في وسائل التواصل
9:16القصص والصور المصغّرة للفيديو العمودي
16:9ترويسات المدونات، والصور المصغّرة للفيديو
21:9اللافتات فائقة العرض
3:2مطبوعات الصور الكلاسيكية

اختر الدقة

تعتمد قيمة image_size على النموذج. يقدّم Flash Lite 1K فقط. ويقدّم Flash القيم 0.5K و1K و2K و4K. ويقدّم Pro القيم 1K و2K و4K. استخدم K بحرف كبير داخل القيمة.

قاعدة بسيطة تُبقي التكاليف معقولة: 1K للمسودات، و2K لصفحات الويب، و4K للطباعة فقط. تكلّف صورة 4K على Flash مبلغ $0.151 مقابل $0.067 عند 1K، أي نحو 2.25 مرة أكثر، لذا فعادة "الأقصى دائمًا" تتراكم بسرعة.

عدّل صورة بأوامر نصية

مُعيد لمس الصور يقف عند مكتب مرتفع ويمسك صورة شخصية مطبوعة بجوار شاشة معايرة

تعدّل نقطة النهاية نفسها الصور أيضًا. فبدلًا من سلسلة نصية بسيطة، يصبح input قائمة تخلط كتلًا نصية وكتلًا للصور. تُرسل الصورة كسلسلة base64 مع نوع MIME الخاص بها.

import base64
from google import genai

client = genai.Client()

with open("portrait.png", "rb") as f:
    encoded = base64.b64encode(f.read()).decode("utf-8")

interaction = client.interactions.create(
    model="gemini-3.1-flash-image",
    input=[
        {
            "type": "text",
            "text": "Replace the background with a sunlit brick wall. Keep the person unchanged.",
        },
        {"type": "image", "data": encoded, "mime_type": "image/png"},
    ],
)

with open("portrait_edit.png", "wb") as f:
    f.write(base64.b64decode(interaction.output_image.data))

لاحظ صياغة أمر التعديل. فهو يذكر ما يتغيّر (الخلفية) وما يبقى (الشخص). ومن دون الجزء الثاني يكون النموذج حرًا في إعادة تصميم الإطار كله.

سلسل التعديلات في محادثة

لا تحتاج إلى إعادة إرسال الصورة مع كل تعديل صغير. مرّر id الخاص بالتفاعل السابق، وسيتذكر النموذج الصورة التي أنشأها للتو:

second = client.interactions.create(
    model="gemini-3.1-flash-image",
    input="Make the light warmer, like late afternoon.",
    previous_interaction_id=interaction.id,
    response_format={
        "type": "image",
        "mime_type": "image/jpeg",
        "aspect_ratio": "4:5",
        "image_size": "2K",
    },
)

حافظ على نفس نسبة العرض إلى الارتفاع كما في الصورة الأولى، وإلا فقد يقصّ النموذج أطراف المشهد أو يمدّه. واحفظ كل interaction.id في قاعدة بياناتك، وستتمكن من الرجوع إلى أي خطوة سابقة في الجلسة، وهذا مفيد في أعمال العملاء حيث يتكرر طلب "ارجع إلى النسخة الثانية" كثيرًا.

اقرأ الاستجابات المختلطة وأضف البحث

طاولة قراءة هادئة في مكتبة مع حاسوب محمول مفتوح وكتب وضوء بعد الظهر

يرد النموذج أحيانًا بجملة من النص و صورة. اختصار output_image مناسب للسكربتات البسيطة، لكن دالة مساعدة تمر على قائمة steps تتعامل مع كل الحالات:

def save_outputs(interaction, prefix="gemini", ext="png"):
    saved = []
    for step in interaction.steps:
        if step.type != "model_output":
            continue
        for block in step.content:
            if block.type == "text":
                print(block.text)
            elif block.type == "image":
                path = f"{prefix}_{len(saved) + 1}.{ext}"
                with open(path, "wb") as f:
                    f.write(base64.b64decode(block.data))
                saved.append(path)
    return saved

تعيد الدالة قائمة بمسارات الملفات. القائمة الفارغة تعني أن النموذج أرسل نصًا فقط، وهذا ليس استثناءً، لذا تحقّق منها قبل أن تفترض وجود ملف.

أسِّس الأوامر النصية على البحث

بعض الصور تعتمد على حقائق تتغير يوميًا: رسم بياني للطقس، أو بطاقة نتائج، أو مخطط أسعار. فعّل Google Search وسيتمكن النموذج من سحب بيانات مباشرة قبل أن يرسم:

interaction = client.interactions.create(
    model="gemini-3.1-flash-image",
    input="Create an infographic of this week's weather in Chicago",
    tools=[{"type": "google_search"}],
    generation_config={"thinking_level": "high"},
)

يقبل إعداد thinking_level القيمة "minimal" أو "high". استخدم minimal عندما تكون السرعة مهمة والتخطيط بسيطًا. واستخدم high عندما يطلب الأمر النصي تخطيطًا منظمًا من عدة أجزاء.

💡 كل صورة تعيدها الواجهة تحمل علامة مائية SynthID، وهي علامة غير مرئية تضيفها Google حتى يمكن التعرف على الصورة بوصفها مولّدة بالذكاء الاصطناعي. لا تحتاج إلى إضافة واحدة بنفسك.

عالج الأخطاء قبل الإنتاج

يد مهندس تمسك قلم تمييز أصفر فوق صفحة مطبوعة من سجلات النظام

تميل استدعاءات الصور إلى الاستغراق وقتًا أطول من استدعاءات النص، ويمكن لموجات الطلبات المتتالية أن تفعّل حدود المعدل. يجنّبك غلاف صغير لإعادة المحاولة معظم المتاعب. يعيد المحاولة عند رموز HTTP 429 و500 و503، ويزيد زمن الانتظار بعد كل فشل:

import time

def generate_with_retry(prompt, retries=4, **kwargs):
    for attempt in range(retries):
        try:
            return client.interactions.create(
                model="gemini-3.1-flash-image",
                input=prompt,
                **kwargs,
            )
        except Exception as exc:
            status = getattr(exc, "status_code", None) or getattr(exc, "code", None)
            if status not in (429, 500, 503) or attempt == retries - 1:
                raise
            time.sleep(2 ** attempt)

حسب إصدار الحزمة، تظهر حالة HTTP على status_code أو على code، لذا تتحقق الدالة من الاثنين. أي خطأ غير قابل لإعادة المحاولة، مثل طلب سيئ، يُرفع فورًا حتى ترى الرسالة الحقيقية.

لمعالجة قائمة من الأوامر النصية، شغّل عددًا قليلًا منها في وقت واحد:

from multiprocessing.pool import ThreadPool

prompts = ["A bowl of oranges", "A lighthouse at dusk", "A forest road in fog"]

with ThreadPool(4) as pool:
    results = pool.map(generate_with_retry, prompts)

ابدأ بأربعة عمال. وإذا استمرت دالة إعادة المحاولة في العمل، فانزل إلى اثنين قبل أن ترفع أي حصة.

تحتاج الأوامر النصية المرفوضة إلى عادة مختلفة. تشير وثائق Google إلى أن إعدادات الأمان المخصصة غير مدعومة في واجهة Interactions API، لذا لا يمكنك تخفيف المرشحات من الشيفرة. عندما ترد استجابة فيها نص دون صورة، سجّل الأمر النصي والنص معًا، ثم أعد كتابة الأمر بوصف أهدأ وأكثر تحديدًا. وإعادة إرسال الأمر نفسه نادرًا ما تغيّر الإجابة، وتهدر الوقت فقط.

3 أخطاء شائعة

  1. استدعاء نموذج متقاعد. أي مقتطف يحتوي gemini-2.5-flash-image يحتاج إلى استبدال سلسلة النموذج بنموذج حالي.
  2. وضع aspect_ratio في generation_config. مكانه في response_format، بجوار image_size.
  3. كتابة سلسلة base64 على القرص. شغّل base64.b64decode() أولًا دائمًا، وإلا فلن يُفتح الملف.

إذا كان لديك لا يزال شيفرة قديمة تستدعي generate_content، فتقول Google إن هذه الواجهة ما زالت مدعومة، وأصبحت مصنّفة بوصفها قديمة (legacy). وبالنسبة للمشاريع الجديدة، فواجهة Interactions API هي التي توصي بها وثائق Google.

راقب التكاليف

صاحب عمل صغير يراجع فاتورة مطبوعة بجوار حاسوب محمول في ورشة لصناعة الفخار

تتناسب التكاليف مع الحجم، لذا احسب الأرقام قبل أي حلقة كبيرة. تكلّف خمسمائة صورة بدقة 2K على Flash مبلغ 500 x $0.101، أي $50.50. وتقدم Google أيضًا تسعيرًا جماعيًا بنحو نصف السعر القياسي للمهام التي يمكنها أن تنتظر:

الدقةالقياسيالجماعي
0.5K$0.045$0.022
1K$0.067$0.034
2K$0.101$0.050
4K$0.151$0.076

نفس الصور الـ500 بدقة 2K عبر الدفعات تكلّف نحو $25. وإذا لم ينتظر أحد النتيجة، كتحديث كتالوج ليلي، فالدفعات هي الخيار الأرخص.

استخدم Nano Banana Pro على PicassoIA

مصمم شاب أمام شاشة كبيرة تعرض شبكة من الصور في استوديو مشرق

ليست كل صورة تحتاج إلى سكربت. إذا أردت اختبار أمر نصي قبل إنفاق رصيد API، أو أردت تسليم المهمة إلى زميل لا يكتب Python، فإن Nano Banana Pro على PicassoIA وسيلة بلا برمجة للحصول على مخرجات تصل إلى 4K من عائلة النماذج نفسها التابعة لـ Google.

  1. افتح صفحة النموذج. انتقل إلى صفحة Nano Banana Pro.
  2. اكتب أمرك النصي. استخدم أسلوب قائمة اللقطات نفسه الذي سبق: الشخص أو الموضوع، والضوء، والعدسة.
  3. أضف صور مرجعية (اختياري). يقبل حقل Image Input ما يصل إلى 14 صورة توجّه الأسلوب أو التكوين أو الموضوع.
  4. اختر نسبة العرض إلى الارتفاع. اختر من بين 11 إعدادًا مسبقًا، بما في ذلك 16:9، و 9:16، و 4:5، و 21:9، و match_input_image.
  5. اختر الدقة. 1K، أو 2K (الافتراضي)، أو 4K.
  6. اختر الصيغة. JPG (الافتراضي) أو PNG.
  7. اضبط مرشح الأمان. block_only_high هو الافتراضي وهو الأكثر تساهلًا، بينما block_low_and_above هو الأشد صرامة.
  8. ولّد ونزّل. أعد التشغيل بأمر نصي معدّل للمقارنة بين النسخ.

طابق إعدادات API مع حقول الصفحة

إذا جرّبت على الصفحة ثم انتقلت إلى الشيفرة، فالإعدادات تتطابق تقريبًا واحدًا لواحد:

حقل PicassoIAالمكافئ في Python API
الأمر النصيinput (كتلة نصية)
Image Inputinput (كتل صور، base64)
aspect_ratioresponse_format["aspect_ratio"]
resolutionresponse_format["image_size"]
output_formatresponse_format["mime_type"]

تضم عائلة Google على PicassoIA أكثر من نموذج واحد. يتولى Nano Banana التعديلات السريعة، ويركّز Nano Banana 2 Lite على السرعة، بينما يركّز Imagen 4 و Imagen 4 Ultra على التفاصيل الواقعية كالصور الفوتوغرافية. وتشغيل الأمر النصي نفسه عبر اثنين منها يستغرق دقيقة، ويبيّن أي أسلوب يناسب مشروعك قبل أن تكتب سطرًا واحدًا من شيفرة التكامل.

أنشئ صورك الخاصة اليوم

صديقان على طاولة مقهى ينظران إلى صورة منظر طبيعي على جهاز لوحي

صار لديك كل شيء: تثبيت يعمل، وأول صورة، والتحكم في الحجم والنسبة، والتعديلات، وطريقة آمنة لقراءة المخرجات المختلطة، وغلاف لإعادة المحاولة، وتقدير للتكلفة يمكنك الوثوق به. اختر مهمة صغيرة واحدة، مثل ترويسة مدونة أو بطاقة منتج، ونفّذها من البداية إلى النهاية بعد ظهر اليوم.

إذا كنت تفضل رؤية النتائج قبل أن تلمس الطرفية، فافتح Picasso IA، واختر نموذجًا مثل Nano Banana Pro، واكتب الأمر النصي الذي كتبته للتو لسكربتك. جرّب ثلاث نسخ، وغيّر نسبة العرض إلى الارتفاع، وقارن. وأفضل أمر نصي تجده هناك يدخل مباشرة في شيفرة Python أعلاه.

هذه الحلقة، أي الاختبار على الصفحة ثم الإطلاق في الشيفرة، هي أسرع طريقة لتحديد الشكل النهائي دون دفع ثمن كل تجربة. افتح Picasso IA، وشغّل أول أمر نصي لك، وشاهد ما يمكنك إنشاءه قبل أن ينتهي بعد الظهر.

شارك هذا المقال

اختر لغتك

مقالات ذات صلة