Modele Gemini mogą przetwarzać obrazy, co umożliwia wielu programistom korzystanie z innowacyjnych przypadków użycia, które w przeszłości wymagały modeli w danej domenie. Gemini potrafi m.in.:
- Dodawanie podpisów i odpowiedzi na pytania dotyczące obrazów
- Transkrypcja i rozumowanie na podstawie plików PDF, w tym do 2 milionów tokenów
- Wykrywanie obiektów na obrazie i zwracanie ich współrzędnych ramki ograniczającej
- Dzielenie na segmenty obiektów na obrazie
Gemini został zaprojektowany od podstaw z myślą o multimodalności, a my wciąż przesuwamy granice tego, co możliwe. Ten przewodnik pokazuje, jak używać interfejsu Gemini API do generowania odpowiedzi tekstowych na podstawie danych wejściowych w postaci obrazów i wykonywania typowych zadań związanych z interpretacją obrazów.
Zanim zaczniesz
Zanim wywołasz interfejs Gemini API, upewnij się, że masz zainstalowany wybrany pakiet SDK oraz skonfigurowany i gotowy do użycia klucz interfejsu Gemini API.
Dane wejściowe dotyczące obrazu
Obrazy możesz przesłać do Gemini na te sposoby:
- Przesłanie pliku obrazu za pomocą interfejsu File API przed wysłaniem żądania do
generateContent
. Używaj tej metody w przypadku plików większych niż 20 MB lub gdy chcesz użyć pliku w kilku żądaniach. - Przekazuj dane obrazów wbudowanych w żądaniu do
generateContent
. Używaj tej metody w przypadku mniejszych plików (o łącznym rozmiarze żądania poniżej 20 MB) lub obrazów pobieranych bezpośrednio z adresów URL.
Przesyłanie pliku obrazu
Do przesyłania plików graficznych możesz użyć interfejsu Files API. Zawsze używaj interfejsu Files API, gdy łączny rozmiar żądania (w tym pliku, promptu tekstowego, instrukcji systemu itp.) przekracza 20 MB lub gdy chcesz użyć tego samego obrazu w kilku promptach.
Poniższy kod przesyła plik obrazu, a potem używa go w wywołaniu funkcji generateContent
.
Python
from google import genai
client = genai.Client(api_key="GOOGLE_API_KEY")
myfile = client.files.upload(file="path/to/sample.jpg")
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=[myfile, "Caption this image."])
print(response.text)
JavaScript
import {
GoogleGenAI,
createUserContent,
createPartFromUri,
} from "@google/genai";
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
async function main() {
const myfile = await ai.files.upload({
file: "path/to/sample.jpg",
config: { mimeType: "image/jpeg" },
});
const response = await ai.models.generateContent({
model: "gemini-2.0-flash",
contents: createUserContent([
createPartFromUri(myfile.uri, myfile.mimeType),
"Caption this image.",
]),
});
console.log(response.text);
}
await main();
Przeczytaj
file, err := client.UploadFileFromPath(ctx, "path/to/sample.jpg", nil)
if err != nil {
log.Fatal(err)
}
defer client.DeleteFile(ctx, file.Name)
model := client.GenerativeModel("gemini-2.0-flash")
resp, err := model.GenerateContent(ctx,
genai.FileData{URI: file.URI},
genai.Text("Caption this image."))
if err != nil {
log.Fatal(err)
}
printResponse(resp)
REST
IMAGE_PATH="path/to/sample.jpg"
MIME_TYPE=$(file -b --mime-type "${IMAGE_PATH}")
NUM_BYTES=$(wc -c < "${IMAGE_PATH}")
DISPLAY_NAME=IMAGE
tmp_header_file=upload-header.tmp
# Initial resumable request defining metadata.
# The upload url is in the response headers dump them to a file.
curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GOOGLE_API_KEY}" \
-D upload-header.tmp \
-H "X-Goog-Upload-Protocol: resumable" \
-H "X-Goog-Upload-Command: start" \
-H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
-H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
-H "Content-Type: application/json" \
-d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null
upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file}"
# Upload the actual bytes.
curl "${upload_url}" \
-H "Content-Length: ${NUM_BYTES}" \
-H "X-Goog-Upload-Offset: 0" \
-H "X-Goog-Upload-Command: upload, finalize" \
--data-binary "@${IMAGE_PATH}" 2> /dev/null > file_info.json
file_uri=$(jq ".file.uri" file_info.json)
echo file_uri=$file_uri
# Now generate content using that file
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [{
"parts":[
{"file_data":{"mime_type": "${MIME_TYPE}", "file_uri": '$file_uri'}},
{"text": "Caption this image."}]
}]
}' 2> /dev/null > response.json
cat response.json
echo
jq ".candidates[].content.parts[].text" response.json
Więcej informacji o pracy z plikami multimedialnymi znajdziesz w interfejsie Files API.
Przekazywanie danych obrazu w ramach tekstu
Zamiast przesyłać plik obrazu, możesz przekazać dane obrazu w żądaniu do generateContent
. Ta metoda jest odpowiednia w przypadku mniejszych obrazów (o łącznym rozmiarze żądania mniejszym niż 20 MB) lub obrazów pobieranych bezpośrednio z adresów URL.
Dane obrazu możesz podać jako ciągi tekstowe z kodowaniem Base64 lub odczytując bezpośrednio pliki lokalne (w zależności od pakietu SDK).
Lokalny plik obrazu:
Python
from google.genai import types
with open('path/to/small-sample.jpg', 'rb') as f:
img_bytes = f.read()
response = client.models.generate_content(
model='gemini-2.0-flash',
contents=[
types.Part.from_bytes(
data=img_bytes,
mime_type='image/jpeg',
),
'Caption this image.'
]
)
print(response.text)
JavaScript
import { GoogleGenAI } from "@google/genai";
import * as fs from "node:fs";
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const base64ImageFile = fs.readFileSync("path/to/small-sample.jpg", {
encoding: "base64",
});
const contents = [
{
inlineData: {
mimeType: "image/jpeg",
data: base64ImageFile,
},
},
{ text: "Caption this image." },
];
const response = await ai.models.generateContent({
model: "gemini-2.0-flash",
contents: contents,
});
console.log(response.text);
Przeczytaj
model := client.GenerativeModel("gemini-2.0-flash")
bytes, err := os.ReadFile("path/to/small-sample.jpg")
if err != nil {
log.Fatal(err)
}
prompt := []genai.Part{
genai.Blob{MIMEType: "image/jpeg", Data: bytes},
genai.Text("Caption this image."),
}
resp, err := model.GenerateContent(ctx, prompt...)
if err != nil {
log.Fatal(err)
}
for _, c := range resp.Candidates {
if c.Content != nil {
fmt.Println(*c.Content)
}
}
REST
IMG_PATH=/path/to/your/image1.jpg
if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
B64FLAGS="--input"
else
B64FLAGS="-w0"
fi
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [{
"parts":[
{
"inline_data": {
"mime_type":"image/jpeg",
"data": "'\$(base64 \$B64FLAGS \$IMG_PATH)'"
}
},
{"text": "Caption this image."},
]
}]
}' 2> /dev/null
Obraz z adresu URL:
Python
from google import genai
from google.genai import types
import requests
image_path = "https://goo.gle/instrument-img"
image = requests.get(image_path)
client = genai.Client(api_key="GOOGLE_API_KEY")
response = client.models.generate_content(
model="gemini-2.0-flash-exp",
contents=["What is this image?",
types.Part.from_bytes(data=image.content, mime_type="image/jpeg")])
print(response.text)
JavaScript
import { GoogleGenAI } from "@google/genai";
async function main() {
const ai = new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY });
const imageUrl = "https://goo.gle/instrument-img";
const response = await fetch(imageUrl);
const imageArrayBuffer = await response.arrayBuffer();
const base64ImageData = Buffer.from(imageArrayBuffer).toString('base64');
const result = await ai.models.generateContent({
model: "gemini-2.0-flash",
contents: [
{
inlineData: {
mimeType: 'image/jpeg',
data: base64ImageData,
},
},
{ text: "Caption this image." }
],
});
console.log(result.text);
}
main();
Przeczytaj
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GOOGLE_API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
model := client.GenerativeModel("gemini-2.0-flash")
// Download the image.
imageResp, err := http.Get("https://goo.gle/instrument-img")
if err != nil {
panic(err)
}
defer imageResp.Body.Close()
imageBytes, err := io.ReadAll(imageResp.Body)
if err != nil {
panic(err)
}
// Create the request.
req := []genai.Part{
genai.ImageData("jpeg", imageBytes),
genai.Text("Caption this image."),
}
// Generate content.
resp, err := model.GenerateContent(ctx, req...)
if err != nil {
panic(err)
}
// Handle the response of generated text.
for _, c := range resp.Candidates {
if c.Content != nil {
fmt.Println(*c.Content)
}
}
}
REST
IMG_URL="https://goo.gle/instrument-img"
MIME_TYPE=$(curl -sIL "$IMG_URL" | grep -i '^content-type:' | awk -F ': ' '{print $2}' | sed 's/\r$//' | head -n 1)
if [[ -z "$MIME_TYPE" || ! "$MIME_TYPE" == image/* ]]; then
MIME_TYPE="image/jpeg"
fi
if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
B64FLAGS="--input"
else
B64FLAGS="-w0"
fi
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [{
"parts":[
{
"inline_data": {
"mime_type":"'"$MIME_TYPE"'",
"data": "'$(curl -sL "$IMG_URL" | base64 $B64FLAGS)'"
}
},
{"text": "Caption this image."}
]
}]
}' 2> /dev/null
Warto pamiętać o kilku kwestiach związanych z danymi obrazu wstawianego w tekście:
- Maksymalny łączny rozmiar żądania to 20 MB, w tym prompty tekstowe, instrukcje systemu i wszystkie pliki podane w postaci inline. Jeśli rozmiar pliku spowoduje, że łączny rozmiar żądania przekroczy 20 MB, użyj interfejsu Files API, aby przesłać plik obrazu, który ma być użyty w żądaniu.
- Jeśli używasz próbki obrazu wiele razy, wydajniej jest przesłać plik obrazu za pomocą interfejsu File API.
Prompty z wieloma obrazami
Możesz podać wiele obrazów w jednym promptzie, dodając wiele obiektów Part
do tablicy contents
. Mogą to być dane wbudowane (pliki lokalne lub adresy URL) i odwołania do interfejsu File API.
Python
from google import genai
from google.genai import types
client = genai.Client(api_key="GOOGLE_API_KEY")
# Upload the first image
image1_path = "path/to/image1.jpg"
uploaded_file = client.files.upload(file=image1_path)
# Prepare the second image as inline data
image2_path = "path/to/image2.png"
with open(image2_path, 'rb') as f:
img2_bytes = f.read()
# Create the prompt with text and multiple images
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=[
"What is different between these two images?",
uploaded_file, # Use the uploaded file reference
types.Part.from_bytes(
data=img2_bytes,
mime_type='image/png'
)
]
)
print(response.text)
JavaScript
import {
GoogleGenAI,
createUserContent,
createPartFromUri,
} from "@google/genai";
import * as fs from "node:fs";
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
async function main() {
// Upload the first image
const image1_path = "path/to/image1.jpg";
const uploadedFile = await ai.files.upload({
file: image1_path,
config: { mimeType: "image/jpeg" },
});
// Prepare the second image as inline data
const image2_path = "path/to/image2.png";
const base64Image2File = fs.readFileSync(image2_path, {
encoding: "base64",
});
// Create the prompt with text and multiple images
const response = await ai.models.generateContent({
model: "gemini-2.0-flash",
contents: createUserContent([
"What is different between these two images?",
createPartFromUri(uploadedFile.uri, uploadedFile.mimeType),
{
inlineData: {
mimeType: "image/png",
data: base64Image2File,
},
},
]),
});
console.log(response.text);
}
await main();
Przeczytaj
+ // Upload the first image
image1Path := "path/to/image1.jpg"
uploadedFile, err := client.UploadFileFromPath(ctx, image1Path, nil)
if err != nil {
log.Fatal(err)
}
defer client.DeleteFile(ctx, uploadedFile.Name)
// Prepare the second image as inline data
image2Path := "path/to/image2.png"
img2Bytes, err := os.ReadFile(image2Path)
if err != nil {
log.Fatal(err)
}
// Create the prompt with text and multiple images
model := client.GenerativeModel("gemini-2.0-flash")
prompt := []genai.Part{
genai.Text("What is different between these two images?"),
genai.FileData{URI: uploadedFile.URI},
genai.Blob{MIMEType: "image/png", Data: img2Bytes},
}
resp, err := model.GenerateContent(ctx, prompt...)
if err != nil {
log.Fatal(err)
}
printResponse(resp)
REST
# Upload the first image
IMAGE1_PATH="path/to/image1.jpg"
MIME1_TYPE=$(file -b --mime-type "${IMAGE1_PATH}")
NUM1_BYTES=$(wc -c < "${IMAGE1_PATH}")
DISPLAY_NAME1=IMAGE1
tmp_header_file1=upload-header1.tmp
curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GOOGLE_API_KEY}" \
-D upload-header1.tmp \
-H "X-Goog-Upload-Protocol: resumable" \
-H "X-Goog-Upload-Command: start" \
-H "X-Goog-Upload-Header-Content-Length: ${NUM1_BYTES}" \
-H "X-Goog-Upload-Header-Content-Type: ${MIME1_TYPE}" \
-H "Content-Type: application/json" \
-d "{'file': {'display_name': '${DISPLAY_NAME1}'}}" 2> /dev/null
upload_url1=$(grep -i "x-goog-upload-url: " "${tmp_header_file1}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file1}"
curl "${upload_url1}" \
-H "Content-Length: ${NUM1_BYTES}" \
-H "X-Goog-Upload-Offset: 0" \
-H "X-Goog-Upload-Command: upload, finalize" \
--data-binary "@${IMAGE1_PATH}" 2> /dev/null > file_info1.json
file1_uri=$(jq ".file.uri" file_info1.json)
echo file1_uri=$file1_uri
# Prepare the second image (inline)
IMAGE2_PATH="path/to/image2.png"
MIME2_TYPE=$(file -b --mime-type "${IMAGE2_PATH}")
if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
B64FLAGS="--input"
else
B64FLAGS="-w0"
fi
IMAGE2_BASE64=$(base64 $B64FLAGS $IMAGE2_PATH)
# Now generate content using both images
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [{
"parts":[
{"text": "What is different between these two images?"},
{"file_data":{"mime_type": "'"${MIME1_TYPE}"'", "file_uri": '$file1_uri'}},
{
"inline_data": {
"mime_type":"'"${MIME2_TYPE}"'",
"data": "'"$IMAGE2_BASE64"'"
}
}
]
}]
}' 2> /dev/null > response.json
cat response.json
echo
jq ".candidates[].content.parts[].text" response.json
Pobieranie prostokąta ograniczającego obiekt
Modele Gemini są trenowane pod kątem identyfikowania obiektów na obrazie i podania ich współrzędnych ramki ograniczającej. Zwracane współrzędne są względne względem wymiarów obrazu, przeskalowane do zakresu [0, 1000]. Musisz odwrócić skalę tych współrzędnych na podstawie pierwotnego rozmiaru obrazu.
Python
prompt = "Detect the all of the prominent items in the image. The box_2d should be [ymin, xmin, ymax, xmax] normalized to 0-1000."
JavaScript
const prompt = "Detect the all of the prominent items in the image. The box_2d should be [ymin, xmin, ymax, xmax] normalized to 0-1000.";
Przeczytaj
prompt := []genai.Part{
genai.FileData{URI: sampleImage.URI},
genai.Text("Detect the all of the prominent items in the image. The box_2d should be [ymin, xmin, ymax, xmax] normalized to 0-1000."),
}
REST
PROMPT="Detect the all of the prominent items in the image. The box_2d should be [ymin, xmin, ymax, xmax] normalized to 0-1000."
Ramki ograniczające możesz używać do wykrywania i lokalizacji obiektów na obrazach oraz w filmach. Dzięki precyzyjnemu identyfikowaniu i oznaczaniu obiektów za pomocą prostokątów ograniczających możesz wykorzystywać wiele aplikacji i ulepszać działanie swoich projektów.
Główne zalety
- Proste: bez względu na to, czy masz doświadczenie w obsłudze technologii widzenia komputerowego, możesz łatwo zintegrować funkcje wykrywania obiektów w swoich aplikacjach.
- Możliwość dostosowania: generowanie ramek ograniczających na podstawie niestandardowych instrukcji (np. „Chcę zobaczyć ramki ograniczające wszystkich zielonych obiektów na tym obrazie”) bez konieczności trenowania niestandardowego modelu.
Szczegóły techniczne
- Wejście: prompt i powiązane obrazy lub klatki wideo.
- Wyjście: ramki ograniczające w formacie
[y_min, x_min, y_max, x_max]
. Górny lewy róg to punkt początkowy. Osiex
iy
są odpowiednio poziome i pionowe. Wartości współrzędnych są normalizowane do zakresu 0–1000 w przypadku każdego obrazu. - Wizualizacja: użytkownicy AI Studio zobaczą ramki ograniczające narysowane w interfejsie.
Deweloperzy Pythona mogą skorzystać z notatnika 2D do analizy przestrzennej lub eksperymentalnego notatnika do wskazywania w 3D.
Normalizowanie współrzędnych
Model zwraca współrzędne ramki ograniczającej w formacie [y_min, x_min, y_max, x_max]
. Aby przekonwertować te znormalizowane współrzędne na współrzędne pikseli oryginalnego obrazu, wykonaj te czynności:
- Podziel każdą współrzędną wyjściową przez 1000.
- Pomnóż współrzędną X przez pierwotną szerokość obrazu.
- Pomnóż współrzędne y przez pierwotną wysokość obrazu.
Aby zobaczyć bardziej szczegółowe przykłady generowania współrzędnych prostokąta ograniczającego i wizualizacji tych współrzędnych na obrazach, zapoznaj się z przykładem w podręczniku dotyczącym wykrywania obiektów.
Segmentacja obrazu
Począwszy od modeli Gemini 2.5, modele Gemini są trenowane nie tylko do wykrywania obiektów, ale też do ich segmentacji i maskowania kontur.
Model prognozuje listę JSON, w której każdy element reprezentuje maskę podziału.
Każdy element ma ograniczenie („box_2d
”) w formacie [y0, x0, y1, x1]
z normalizowanymi współrzędnymi w zakresie od 0 do 1000, etykietą („label
”), która identyfikuje obiekt, oraz maską segmentacji wewnątrz ogranicznika w formacie obrazu png zakodowanego w formacie base64, który jest mapą prawdopodobieństwa z wartościami od 0 do 255.
Rozmiar maski musi być dostosowany do wymiarów prostokąta ograniczającego, a następnie zamienić na binarną wartość na podstawie progu ufności (127 dla punktu środkowego).
Python
prompt = """
Give the segmentation masks for the wooden and glass items.
Output a JSON list of segmentation masks where each entry contains the 2D
bounding box in the key "box_2d", the segmentation mask in key "mask", and
the text label in the key "label". Use descriptive labels.
"""
JavaScript
const prompt = `
Give the segmentation masks for the wooden and glass items.
Output a JSON list of segmentation masks where each entry contains the 2D
bounding box in the key "box_2d", the segmentation mask in key "mask", and
the text label in the key "label". Use descriptive labels.
`;
Przeczytaj
prompt := []genai.Part{
genai.FileData{URI: sampleImage.URI},
genai.Text(`
Give the segmentation masks for the wooden and glass items.
Output a JSON list of segmentation masks where each entry contains the 2D
bounding box in the key "box_2d", the segmentation mask in key "mask", and
the text label in the key "label". Use descriptive labels.
`),
}
REST
PROMPT='''
Give the segmentation masks for the wooden and glass items.
Output a JSON list of segmentation masks where each entry contains the 2D
bounding box in the key "box_2d", the segmentation mask in key "mask", and
the text label in the key "label". Use descriptive labels.
'''

Aby zobaczyć bardziej szczegółowy przykład, zapoznaj się z przykładem podziału na segmenty w przewodniku z przepisami.
Obsługiwane formaty obrazów
Gemini obsługuje te typy MIME formatu obrazu:
- PNG –
image/png
- JPEG –
image/jpeg
- WEBP –
image/webp
- HEIC –
image/heic
- HEIF –
image/heif
Szczegóły techniczne dotyczące obrazów
- Limit plików: modele Gemini 2.5 Pro, 2.0 Flash, 1.5 Pro i 1.5 Flash obsługują maksymalnie 3600 plików z obrazami na prośbę.
- Obliczanie tokena:
- Gemini 1.5 Flash i Gemini 1.5 Pro: 258 tokenów, jeśli oba wymiary są mniejsze niż 384 piksele. Większe obrazy są dzielone na kafelki (minimalny rozmiar kafelka to 256 pikseli, maksymalny 768 pikseli, a po zmniejszeniu 768 x 768), a każdy kafelek kosztuje 258 tokenów.
- Gemini 2.0 Flash: 258 tokenów, jeśli oba wymiary są mniejsze niż 384 piksele. Większe obrazy są dzielone na kafelki o wymiarach 768 x 768 pikseli, z których każdy kosztuje 258 tokenów.
- Sprawdzone metody:
- Upewnij się, że obrazy są prawidłowo obrócone.
- Używaj wyraźnych, nierozmytych obrazów.
- Jeśli używasz pojedynczego obrazu z tekstem, umieść prompt tekstowy po części obrazu w tablicy
contents
.
Co dalej?
Z tego przewodnika dowiesz się, jak przesyłać pliki z obrazami i generować tekst na podstawie obrazów wejściowych. Więcej informacji znajdziesz w tych materiałach:
- Instrukcje systemowe: instrukcje systemowe umożliwiają kierowanie działaniem modelu na podstawie konkretnych potrzeb i przypadków użycia.
- Interpretacja filmów: dowiedz się, jak pracować z danymi wejściowymi wideo.
- Files API: dowiedz się więcej o przesyłaniu plików i zarządzaniu nimi w Gemini.
- Strategie wyświetlania promptów dotyczących plików: interfejs Gemini API obsługuje prompty z tekstem, obrazem, dźwiękiem i danymi wideo, które są też nazywane promptami multimodalnymi.
- Wskazówki dotyczące bezpieczeństwa: modele generatywnej AI czasami generują nieoczekiwane wyniki, np. niedokładne, stronnicze lub obraźliwe. Przetwarzanie końcowe i sprawdzanie przez weryfikatorów są niezbędne do ograniczenia ryzyka szkód wynikających z takich danych wyjściowych.