فهم الصور في Gemini API: إدخال الصور والتحويل من صورة إلى نص في Python

أرسل صورة إلى Gemini API من Python واحصل على نص في المقابل. يعرض هذا المقال البايتات المضمنة، وطريقة Files API، والأوامر النصية متعددة الصور، ثم يحوّل الاستدعاء نفسه إلى تسميات توضيحية، وقراءة OCR للإيصالات، ومربعات محيطة، مع حساب التوكنات، وحدود الحجم، وحلول للأخطاء الشائعة.

فهم الصور في Gemini API: إدخال الصور والتحويل من صورة إلى نص في Python
Cristian Da Conceicao
مؤسس Picasso IA

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

هناك تغيير مهم للكود أدناه. توضح وثائق Google الحالية أن إدخال الصور يتم عبر Interactions API (client.interactions.create)، وتصنّف طريقة generateContent الأقدم بأنها قديمة (legacy)، مع تأكيدها أنها ما زالت مدعومة بالكامل. يظهر الإصداران هنا، لذا يمكنك لصق الإصدار الذي يطابق مشروعك.

ما الذي يفعله إدخال الصور فعليًا؟

امرأة تمسك هاتفًا فوق صورة مطبوعة لسوق، بجانب حاسوب محمول

نماذج Gemini متعددة الوسائط، أي أن طلبًا واحدًا يمكن أن يحتوي على أجزاء نصية وأجزاء صورية جنبًا إلى جنب. ترسل صورة مع تعليمة، ويجيب النموذج بنص. لا توجد نقطة نهاية منفصلة للرؤية، ولا خطوة معالجة مسبقة، ولا مكتبة OCR تحتاج إلى تثبيت أولًا. الصورة مجرد جزء آخر من الأمر النصي.

من الصورة إلى النص في طلب واحد

يُستخدم نمط الاستدعاء نفسه في مهام مختلفة جدًا، بحسب التعليمة التي تضيفها:

  • التسمية التوضيحية: جملة واحدة لمنشور على وسائل التواصل أو وصف لصفحة.
  • النص البديل: أوصاف قصيرة وحرفية لإمكانية الوصول.
  • أسئلة بصرية: "كم عدد الكراسي حول الطاولة؟" أو "هل الملصق متجه إلى الأمام؟"
  • OCR: نص مستخرج من الإيصالات واللافتات والنماذج والملاحظات المكتوبة بخط اليد.
  • الكشف: مربعات محيطة مُسمّاة تُعاد بصيغة JSON.
  • المقارنة: الفروق بين صورتين أو أكثر.

💡 تعامل مع التعليمة على أنها المنتج. النموذج واحد في كل الحالات. الأمر النصي هو ما يحدد هل ستحصل على قصيدة عن صورة أم على مجموع JSON نظيف.

نماذج تقبل الصور

تسرد صفحة النماذج لدى Google معرّفات النماذج الحالية التالية، وجميعها تقبل إدخال الصور:

معرّف النموذجالحالةوصف Google
gemini-3.8-flashمستقرأذكى نموذج من فئة Flash
gemini-3.7-flashمستقرالبرمجة المعقدة وسير العمل القائم على الوكلاء
gemini-3.6-flashمستقرالعمل متعدد الوسائط العام
gemini-3.5-flash (Gemini 3.5 Flash)مستقرأحمال عمل عالية الإنتاجية
gemini-3.1-pro-preview (Gemini 3.1 Pro)معاينةحل المشكلات المعقدة
gemini-3-flash-preview (Gemini 3 Flash)معاينةمهام متعددة الوسائط

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

إعداد بيئة Python

حاسوب محمول لمطوّر على مكتب من خشب الجوز، مع نافذة طرفية مفتوحة عند الغسق

دقيقتان من الإعداد الآن توفّران عليك نصف يوم من أخطاء الاستيراد المربكة لاحقًا.

تثبيت SDK

الحزمة الرسمية هي google-genai. تستخدم الأمثلة أدناه أيضًا مكتبة Pydantic للمخرجات المنظمة، ومكتبة Pillow لرسم المربعات.

pip install -U google-genai pydantic pillow

لا تخلط بينها وبين حزمة google-generativeai الأقدم. تُستورد الحزمة الجديدة باسم from google import genai، وتفترض كل المقاطع هنا ذلك.

إنشاء العميل

أنشئ مفتاح API من Google AI Studio، واحفظه في اسم متغير البيئة الذي تحدده صفحة الإعداد لدى Google، وأبقه خارج نظام التحكم بالإصدارات. يقرأ العميل المفتاح تلقائيًا:

from google import genai

client = genai.Client()

بلا وسائط، وبلا أسرار مكتوبة مباشرة في السكربت. يعيد كل مثال يلي استخدام client نفسه.

إرسال صورة بثلاث طرق

اختر الطريقة حسب حجم الملف وإعادة استخدامه، لا حسب العادة.

البايتات المضمنة للملفات الصغيرة

فتحة بطاقة ذاكرة كاميرا مع مطبوعات لبلدة ساحلية خلفها

البايتات المضمنة هي أقصر طريق. تقرأ الملف، وتشفّره، وترسله مع الأمر النصي. تبدو نسخة Interactions API الحالية هكذا:

import base64
from pathlib import Path

image_bytes = Path("street-market.jpg").read_bytes()

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input=[
        {"type": "text", "text": "Caption this image in one sentence."},
        {
            "type": "image",
            "data": base64.b64encode(image_bytes).decode("utf-8"),
            "mime_type": "image/jpeg",
        },
    ],
)

print(interaction.output_text)

نسخة generateContent القديمة ما زالت صالحة وأقصر قليلًا، لأن الحزمة تتولى الترميز:

from google.genai import types

response = client.models.generate_content(
    model="gemini-3.8-flash",
    contents=[
        types.Part.from_bytes(data=image_bytes, mime_type="image/jpeg"),
        "Caption this image in one sentence.",
    ],
)

print(response.text)

تحدّ البايتات المضمنة من إجمالي الطلب (نص الأمر، وتعليمات النظام، وبايتات الصورة معًا) إلى 20 ميغابايت. صورة هاتف واحدة تتسع بسهولة، أما دفعة من المسوحات بالدقة الكاملة فلا تتسع.

Files API للصور الأكبر

مصوّر بجانب مطبوعة كبيرة لبحيرة جبلية، وهو يمسك قرصًا صلبًا

عندما يتجاوز الطلب 20 ميغابايت، أو عندما تريد طرح عدة أسئلة عن صورة واحدة، ارفعها مرة واحدة وأشر إليها عبر URI:

uploaded = client.files.upload(file="mountain-lake-print.jpg")

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input=[
        {"type": "text", "text": "Describe the scene and list any visible text."},
        {
            "type": "image",
            "uri": uploaded.uri,
            "mime_type": uploaded.mime_type,
        },
    ],
)

print(interaction.output_text)

تُخزَّن الملفات المرفوعة مؤقتًا، لذا تعامل مع Files API كوسيلة للتسليم لا كأرشيف. احتفظ بنسخ أصلية من ملفاتك.

صور متعددة في أمر نصي واحد

مطبوعتان لغرفة معيشة متطابقتان تقريبًا، مع إشارة إلى اختلاف واحد

أضف أجزاء صورة إضافية إلى قائمة input نفسها. تسمح وثائق Google بما يصل إلى 3,600 ملف صورة في طلب واحد.

before = client.files.upload(file="living-room-before.jpg")
after = client.files.upload(file="living-room-after.jpg")

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input=[
        {
            "type": "text",
            "text": "The first image is BEFORE and the second is AFTER. "
                    "What is different between them?",
        },
        {"type": "image", "uri": before.uri, "mime_type": before.mime_type},
        {"type": "image", "uri": after.uri, "mime_type": after.mime_type},
    ],
)

print(interaction.output_text)

وضّح في النص أي صورة هي أي. يرى النموذج قائمة مرتبة، وعبارة عامة مثل "قارن هذه" تجعله يخمّن الأدوار.

أوامر نصية تحوّل الصور إلى نص

لا يتغير الاستدعاء أبدًا. التعليمة وحدها تتغير.

الهدفنمط الأمر النصيشكل المخرجات
التسمية التوضيحية"صِف هذه الصورة في جملة واحدة."نص عادي
النص البديل"اكتب نصًا بديلًا بأقل من 125 حرفًا. صِف ما هو مرئي فقط."نص عادي
سؤال بصري"كم صندوقًا أحمر على الرف الأيسر؟"إجابة قصيرة
الاستخراج"استخرج اسم التاجر والتاريخ والمجموع."JSON عبر مخطط (schema)
الكشف"اكشف كل العناصر البارزة في الصورة."JSON عبر مخطط (schema)

التسميات التوضيحية والنص البديل

محرر ويب يكتب نصًا بديلًا في دفتر بجانب شاشة

أكبر تحسين في الجودة يأتي من القيود. تعليمة "Describe this image" تعيد فقرة، أما "Write alt text under 125 characters, no opening phrase like 'image of'" فتعيد شيئًا يمكنك نشره.

prompt = (
    "Write alt text for this photo in under 125 characters. "
    "Describe only what is visible. Do not start with 'image of'."
)

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

OCR والإيصالات

إيصالات مجعّدة وقائمة مكتوبة بخط اليد على منضدة مقهى

الإيصالات اختبار جيد لأنها تجمع بين النص المطبوع والأرقام والتجعيدات. اطلب مخرجات منظمة بدل النثر. عرّف الشكل باستخدام Pydantic، ومرّر مخطط JSON الخاص به عبر response_format:

from pydantic import BaseModel

class LineItem(BaseModel):
    name: str
    price: float

class Receipt(BaseModel):
    merchant: str
    date: str
    items: list[LineItem]
    total: float

receipt = client.files.upload(file="receipt.jpg")

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input=[
        {
            "type": "text",
            "text": "Extract the merchant, date, line items, and total.",
        },
        {"type": "image", "uri": receipt.uri, "mime_type": receipt.mime_type},
    ],
    response_format={
        "type": "text",
        "mime_type": "application/json",
        "schema": Receipt.model_json_schema(),
    },
)

data = Receipt.model_validate_json(interaction.output_text)
print(data.merchant, data.total)

إذا أعاد النموذج شيئًا لا يطابق المخطط، فإن model_validate_json يطلق خطأً في الحال، بدل أن تتسرب بيانات فاسدة إلى قاعدة بياناتك.

كشف الأجسام بالمربعات

ممر بقالة فيه صناديق من البرتقال والطماطم والفلفل

يمكن أن يعيد Gemini المربعات المحيطة بصيغة [ymin, xmin, ymax, xmax]، مطبّعة على مقياس من 0 إلى 1000. اطلبها باستخدام مخطط، ثم حوّلها إلى بكسلات وارسمها:

from PIL import Image, ImageDraw
from pydantic import BaseModel, Field

class Box(BaseModel):
    box_2d: list[int] = Field(
        description="[ymin, xmin, ymax, xmax] normalized to 0-1000."
    )
    label: str

class Boxes(BaseModel):
    boxes: list[Box]

aisle = client.files.upload(file="grocery-aisle.jpg")

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input=[
        {"type": "text", "text": "Detect all of the prominent items in the image."},
        {"type": "image", "uri": aisle.uri, "mime_type": aisle.mime_type},
    ],
    response_format={
        "type": "text",
        "mime_type": "application/json",
        "schema": Boxes.model_json_schema(),
    },
)

result = Boxes.model_validate_json(interaction.output_text)

image = Image.open("grocery-aisle.jpg")
width, height = image.size
draw = ImageDraw.Draw(image)

for item in result.boxes:
    ymin, xmin, ymax, xmax = item.box_2d
    left, top = xmin / 1000 * width, ymin / 1000 * height
    right, bottom = xmax / 1000 * width, ymax / 1000 * height
    draw.rectangle((left, top, right, bottom), outline="red", width=4)
    draw.text((left + 6, top + 6), item.label, fill="red")

image.save("grocery-aisle-boxes.jpg")

يتبع التجزئة (segmentation) النمط نفسه. يضيف المخطط حقل mask يحمل نقاط المضلع، وهي أيضًا مطبّعة على 0 إلى 1000. توصي Google بضبط مستوى التفكير على minimal للتجزئة، لأن التفكير الموسّع يضيف زمن انتظار دون تحسين المضلعات.

الحدود والتوكنات والتكاليف

ورقة مصغّرات لإطارات صغيرة على طاولة إضاءة مع عدسة تكبير

تُحتسب الصور كتوكنات، ويعتمد العدد على الحجم. معرفة القاعدة تتيح لك توقع الفاتورة قبل تشغيل الدفعة.

كيف تُحتسب الصور كتوكنات

وضع الصورةتكلفة التوكنات
كلا البعدين 384 بكسل أو أقل258 توكنًا
صورة أكبرتُقسَّم إلى بلاطات بحجم 768 x 768 بكسل، بواقع 258 توكنًا لكل بلاطة
مثال: صورة تنقسم إلى أربع بلاطات4 x 258 = 1,032 توكنًا

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

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

حدود التنسيق والحجم

الحدالقيمة
الصيغ المدعومةPNG, JPEG, WEBP, HEIC, HEIF
الصور لكل طلبحتى 3,600 ملف
حجم الطلب المضمن20 ميغابايت إجمالًا (النص والتعليمات والبايتات)
مقياس المربعات المحيطةمن 0 إلى 1000، والترتيب [ymin, xmin, ymax, xmax]

💡 إذا أرسلت مهمة عدة صور مع أمر نصي طويل، فاحسب الإجمالي المضمَّن قبل أن تصل إلى حد 20 ميغابايت. التحويل إلى Files API في منتصف المشروع سهل، لكن القيام به مبكرًا يتجنب فشلًا متقطعًا في الساعة 2 صباحًا.

ثلاثة أخطاء تهدر الاستدعاءات

معظم الطلبات الفاشلة تأتي من القائمة القصيرة نفسها.

نوع MIME خاطئ

يجب أن يطابق mime_type الملف الحقيقي. تسمية ملف PNG باسم image/jpeg أو تمرير صيغة غير مدعومة ينتج أخطاء أو نتائج ضعيفة. دع Python يحدد النوع بدل كتابة النصوص يدويًا:

import mimetypes

def mime_for(path: str) -> str:
    mime, _ = mimetypes.guess_type(path)
    if mime is None:
        raise ValueError(f"Unknown image type: {path}")
    return mime

بعض الأنظمة لا تعرف نوع HEIC، لذا أضف تعيينًا يدويًا بسيطًا إذا كنت تقبل الملفات الأصلية من iPhone.

المربعات في المكان الخطأ

إذا وقعت المستطيلات المرسومة في أماكن غريبة، تحقق من أمرين. أولًا، الترتيب هو [ymin, xmin, ymax, xmax]، مع القيمة العمودية أولًا، ويقرؤه كثيرون على أنه x ثم y. ثانيًا، الأرقام على مقياس من 0 إلى 1000 وليست بكسلات. اقسم على 1000، ثم اضرب في العرض أو الارتفاع الحقيقي.

نص حر حيث يجب أن يكون JSON

كتابة "return JSON" في الأمر النصي تنجح حتى يلفّ النموذج الإجابة في كتلة كود أو يضيف جملة ودية. مرّر مخططًا عبر response_format واحلل الناتج باستخدام model_validate_json. عندها يعيش العقد داخل الكود، حيث تفشل الاستجابة السيئة بصوت عالٍ وتصل الجيدة مع أنواع محددة.

جرّب Gemini 3.5 Flash دون كود

قبل كتابة Python، اختبر الأمر النصي في المتصفح. يعمل Gemini 3.5 Flash على PicassoIA ويقبل الصور مباشرة، لذا يمكنك ضبط التعليمة في ثوانٍ ثم لصقها في سكربتك لاحقًا.

  1. افتح صفحة Gemini 3.5 Flash على PicassoIA.
  2. أرفق صورك في حقل Images. يقبل النموذج حتى 10 صور لكل تشغيل، بحجم يصل إلى 7 ميغابايت للصورة.
  3. اكتب التعليمة في حقل Prompt بالصيغة نفسها التي تنوي إرسالها من Python.
  4. اختياريًا، املأ حقل System Instruction لتحديد الدور، مثل "You write alt text under 125 characters."
  5. اختر Thinking Level من بين none أو low أو high. اتركه على none للتسميات التوضيحية، وارفعه للاستدلال المكثف.
  6. اضبط Temperature على قيمة منخفضة للاستخراج و OCR، وعلى قيمة أعلى للتسميات الإبداعية.
  7. شغّله، وقارن الإجابة بما أردته، وعدّل الصياغة قبل نسخها إلى الكود.
الحقلوظيفتهالقيمة الابتدائية
Promptالتعليمة المرسلة مع الصورصياغتك الإنتاجية الدقيقة
Imagesحتى 10 ملفات، 7 ميغابايت لكل منهاصورة واحدة أثناء الاختبار
System Instructionيحدد دور النموذججملة قصيرة واحدة
Thinking Levelnone أو low أو highnone
Temperatureالعشوائية من 0 إلى 20.2 لقراءة OCR، و1 للتسميات التوضيحية
Max Output Tokensيحدد طول الإجابةالافتراضي مناسب

حدود PicassoIA تختلف عن حدود API الخام المذكورة أعلاه، لذا اعتبر الصفحة مختبرًا للأوامر النصية، واعتبر API مسار الإنتاج. للحصول على رأي ثانٍ في صورة صعبة، شغّل الأمر النصي نفسه عبر Gemini 3.1 Pro، أو Qwen3.7-Plus، الذي يفسّر الصور والنص معًا، أو Granite Vision 4.1 4B، المصمم للرسوم البيانية والجداول.

أنشئ صور اختبار خاصة بك

لا تحتاج إلى مجلد من الصور الحقيقية للبدء. أنشئ مكتبًا فوضويًا أو رفًا لبقالة أو شارعًا ممطرًا أو إيصالًا مجعّدًا باستخدام PicassoIA Image أو Seedream 4.5، ثم مرّر كل نتيجة إلى Gemini 3.5 Flash وانظر ما الذي يقرؤه منها.

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

افتح PicassoIA، وأنشئ أول صورة اختبار لك، وشغّل أمرك النصي الخاص. تصفّح كل النماذج المتاحة على picassoia.com/en/all-models، وادمج مولّد صور مع نموذج رؤية لبناء سير عمل تحويل الصورة إلى نص الخاص بك.

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

اختر لغتك

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