فهم الصور في Gemini API: إدخال الصور والتحويل من صورة إلى نص في Python
أرسل صورة إلى Gemini API من Python واحصل على نص في المقابل. يعرض هذا المقال البايتات المضمنة، وطريقة Files API، والأوامر النصية متعددة الصور، ثم يحوّل الاستدعاء نفسه إلى تسميات توضيحية، وقراءة OCR للإيصالات، ومربعات محيطة، مع حساب التوكنات، وحدود الحجم، وحلول للأخطاء الشائعة.
لديك صورة وتحتاج إلى كلمات. صورة منتج تحتاج إلى نص بديل، أو إيصال تحتاج إلى إجماليه، أو رف تحتاج إلى عدّ محتوياته. تقبل Gemini API الصورة كجزء من الأمر النصي وتعيد نصًا، لذا تتم المهمة كاملة في استدعاء واحد بلغة Python من نحو عشرة أسطر. يتبع هذا المقال ترتيب المشكلات كما تظهر فعليًا: الإعداد، وثلاث طرق لإرسال الصورة، والأوامر النصية التي تعيد نصًا قابلًا للاستخدام، وتكلفة التوكنات، والأخطاء التي تستهلك الطلبات.
هناك تغيير مهم للكود أدناه. توضح وثائق Google الحالية أن إدخال الصور يتم عبر Interactions API (client.interactions.create)، وتصنّف طريقة generateContent الأقدم بأنها قديمة (legacy)، مع تأكيدها أنها ما زالت مدعومة بالكامل. يظهر الإصداران هنا، لذا يمكنك لصق الإصدار الذي يطابق مشروعك.
ما الذي يفعله إدخال الصور فعليًا؟
نماذج Gemini متعددة الوسائط، أي أن طلبًا واحدًا يمكن أن يحتوي على أجزاء نصية وأجزاء صورية جنبًا إلى جنب. ترسل صورة مع تعليمة، ويجيب النموذج بنص. لا توجد نقطة نهاية منفصلة للرؤية، ولا خطوة معالجة مسبقة، ولا مكتبة OCR تحتاج إلى تثبيت أولًا. الصورة مجرد جزء آخر من الأمر النصي.
من الصورة إلى النص في طلب واحد
يُستخدم نمط الاستدعاء نفسه في مهام مختلفة جدًا، بحسب التعليمة التي تضيفها:
التسمية التوضيحية: جملة واحدة لمنشور على وسائل التواصل أو وصف لصفحة.
النص البديل: أوصاف قصيرة وحرفية لإمكانية الوصول.
أسئلة بصرية: "كم عدد الكراسي حول الطاولة؟" أو "هل الملصق متجه إلى الأمام؟"
OCR: نص مستخرج من الإيصالات واللافتات والنماذج والملاحظات المكتوبة بخط اليد.
الكشف: مربعات محيطة مُسمّاة تُعاد بصيغة JSON.
المقارنة: الفروق بين صورتين أو أكثر.
💡 تعامل مع التعليمة على أنها المنتج. النموذج واحد في كل الحالات. الأمر النصي هو ما يحدد هل ستحصل على قصيدة عن صورة أم على مجموع JSON نظيف.
نماذج تقبل الصور
تسرد صفحة النماذج لدى Google معرّفات النماذج الحالية التالية، وجميعها تقبل إدخال الصور:
تتغير قوائم النماذج بسرعة، لذا تحقق من صفحة النماذج قبل أن تثبّت معرّفًا في الإنتاج. في عمل الصور، يُعد نموذج 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 يحدد النوع بدل كتابة النصوص يدويًا:
بعض الأنظمة لا تعرف نوع 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 ويقبل الصور مباشرة، لذا يمكنك ضبط التعليمة في ثوانٍ ثم لصقها في سكربتك لاحقًا.
أرفق صورك في حقل Images. يقبل النموذج حتى 10 صور لكل تشغيل، بحجم يصل إلى 7 ميغابايت للصورة.
اكتب التعليمة في حقل Prompt بالصيغة نفسها التي تنوي إرسالها من Python.
اختياريًا، املأ حقل System Instruction لتحديد الدور، مثل "You write alt text under 125 characters."
اختر Thinking Level من بين none أو low أو high. اتركه على none للتسميات التوضيحية، وارفعه للاستدلال المكثف.
اضبط Temperature على قيمة منخفضة للاستخراج و OCR، وعلى قيمة أعلى للتسميات الإبداعية.
شغّله، وقارن الإجابة بما أردته، وعدّل الصياغة قبل نسخها إلى الكود.
الحقل
وظيفته
القيمة الابتدائية
Prompt
التعليمة المرسلة مع الصور
صياغتك الإنتاجية الدقيقة
Images
حتى 10 ملفات، 7 ميغابايت لكل منها
صورة واحدة أثناء الاختبار
System Instruction
يحدد دور النموذج
جملة قصيرة واحدة
Thinking Level
none أو low أو high
none
Temperature
العشوائية من 0 إلى 2
0.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، وادمج مولّد صور مع نموذج رؤية لبناء سير عمل تحويل الصورة إلى نص الخاص بك.