Gemini 모델은 이미지를 처리할 수 있으므로 이전에는 도메인별 모델이 필요했던 많은 첨단 개발자 사용 사례를 지원할 수 있습니다. Gemini의 비전 기능에는 다음과 같은 기능이 포함됩니다.
- 이미지에 대한 자막 및 질문에 답변
- 최대 2백만 개의 토큰을 포함하여 PDF를 텍스트로 변환하고 추론
- 이미지에서 객체를 감지하고 객체의 경계 상자 좌표를 반환합니다.
- 이미지 내 객체 세그먼트
Gemini는 처음부터 멀티모달로 빌드되었으며 Google은 계속해서 가능한 한계를 넓혀 나가고 있습니다. 이 가이드에서는 Gemini API를 사용하여 이미지 입력을 기반으로 텍스트 응답을 생성하고 일반적인 이미지 이해 작업을 실행하는 방법을 보여줍니다.
시작하기 전에
Gemini API를 호출하기 전에 선택한 SDK가 설치되어 있고 Gemini API 키가 구성되어 있고 사용할 준비가 되었는지 확인합니다.
이미지 입력
다음과 같은 방법으로 이미지를 Gemini에 입력으로 제공할 수 있습니다.
generateContent
에 요청하기 전에 File API를 사용하여 이미지 파일을 업로드합니다. 20MB를 초과하는 파일이나 여러 요청에서 파일을 재사용하려는 경우에 이 메서드를 사용하세요.generateContent
에 대한 요청과 함께 인라인 이미지 데이터를 전달합니다. 이 메서드는 크기가 작은 파일(총 요청 크기가 20MB 미만) 또는 URL에서 직접 가져온 이미지에 사용합니다.
이미지 파일 업로드
Files API를 사용하여 이미지 파일을 업로드할 수 있습니다. 총 요청 크기 (파일, 텍스트 프롬프트, 시스템 안내 등 포함)가 20MB를 초과하거나 여러 프롬프트에서 동일한 이미지를 사용할 계획인 경우 항상 Files API를 사용하세요.
다음 코드는 이미지 파일을 업로드한 다음 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)
자바스크립트
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();
Go
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
미디어 파일 작업에 관한 자세한 내용은 Files API를 참고하세요.
인라인으로 이미지 데이터 전달
이미지 파일을 업로드하는 대신 요청에서 인라인 이미지 데이터를 generateContent
에 전달할 수 있습니다. 이는 작은 이미지(총 요청 크기가 20MB 미만) 또는 URL에서 직접 가져온 이미지에 적합합니다.
이미지 데이터를 Base64로 인코딩된 문자열로 제공하거나 로컬 파일을 직접 읽어서 제공할 수 있습니다 (SDK에 따라 다름).
로컬 이미지 파일:
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)
자바스크립트
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);
Go
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
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)
자바스크립트
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();
Go
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
인라인 이미지 데이터와 관련하여 유의해야 할 사항은 다음과 같습니다.
- 총 요청 크기의 최대값은 20MB이며 여기에는 텍스트 프롬프트, 시스템 안내, 인라인으로 제공된 모든 파일이 포함됩니다. 파일 크기로 인해 총 요청 크기가 20MB를 초과하는 경우 Files API를 사용하여 요청에 사용할 이미지 파일을 업로드합니다.
- 이미지 샘플을 여러 번 사용하는 경우 File API를 사용하여 이미지 파일을 업로드하는 것이 더 효율적입니다.
여러 이미지를 사용한 프롬프트
contents
배열에 여러 이미지 Part
객체를 포함하여 단일 프롬프트에 여러 이미지를 제공할 수 있습니다. 인라인 데이터(로컬 파일 또는 URL)와 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)
자바스크립트
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();
Go
+ // 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
객체의 경계 상자 가져오기
Gemini 모델은 이미지에서 객체를 식별하고 경계 상자 좌표를 제공하도록 학습됩니다. 좌표는 이미지 크기를 기준으로 반환되며 [0, 1000]으로 크기가 조정됩니다. 원본 이미지 크기에 따라 이러한 좌표의 크기를 조정해야 합니다.
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."
자바스크립트
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.";
Go
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."
이미지와 동영상 내에서 객체 감지 및 위치 지정에 경계 상자를 사용할 수 있습니다. 경계 상자로 객체를 정확하게 식별하고 윤곽을 그려 다양한 애플리케이션을 활용하고 프로젝트 인텔리전스를 향상시킬 수 있습니다.
주요 이점
- 간단함: 컴퓨터 비전 전문성과 관계없이 객체 감지 기능을 애플리케이션에 손쉽게 통합할 수 있습니다.
- 맞춤설정 가능: 커스텀 모델을 학습시키지 않고도 커스텀 안내(예: '이 이미지의 모든 녹색 객체의 경계 상자를 보고 싶습니다')에 따라 경계 상자를 생성할 수 있습니다.
기술 세부정보
- 입력: 프롬프트와 관련 이미지 또는 동영상 프레임입니다.
- 출력:
[y_min, x_min, y_max, x_max]
형식의 경계 상자입니다. 왼쪽 상단이 원점입니다.x
및y
축은 각각 가로 및 세로로 이동합니다. 좌표 값은 모든 이미지에 대해 0~1,000으로 정규화됩니다. - 시각화: AI 스튜디오 사용자에게는 UI 내에 표시된 경계 상자가 표시됩니다.
Python 개발자의 경우 2D 공간 이해 노트북 또는 실험용 3D 포인팅 노트북을 사용해 보세요.
좌표 정규화
모델은 [y_min, x_min, y_max, x_max]
형식의 경계 상자 좌표를 반환합니다. 이러한 정규화된 좌표를 원본 이미지의 픽셀 좌표로 변환하려면 다음 단계를 따르세요.
- 각 출력 좌표를 1,000으로 나눕니다.
- x 좌표에 원본 이미지 너비를 곱합니다.
- y 좌표에 원본 이미지 높이를 곱합니다.
경계 상자 좌표를 생성하고 이미지에 시각화하는 방법에 관한 자세한 예시는 객체 감지 쿠킹북 예시를 참고하세요.
이미지 세분화
Gemini 2.5 모델부터 Gemini 모델은 항목을 감지할 뿐만 아니라 항목을 분할하고 윤곽의 마스크를 제공하도록 학습됩니다.
모델은 각 항목이 세분화 마스크를 나타내는 JSON 목록을 예측합니다.
각 항목에는 0~1000 사이의 정규화된 좌표를 갖는 [y0, x0, y1, x1]
형식의 경계 상자('box_2d
'), 객체를 식별하는 라벨('label
'), 마지막으로 경계 상자 내부의 세분화 마스크(값이 0~255 사이인 확률 맵인 base64 인코딩된 png)가 있습니다.
마스크의 크기를 경계 상자 크기와 일치하도록 조정한 다음 신뢰도 임계값 (중점의 경우 127)에서 바이너리화해야 합니다.
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.
"""
자바스크립트
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.
`;
Go
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.
'''

자세한 예는 레시피 가이드의 세분화 예를 참고하세요.
지원되는 이미지 형식
Gemini는 다음과 같은 이미지 형식 MIME 유형을 지원합니다.
- PNG -
image/png
- JPEG -
image/jpeg
- WEBP -
image/webp
- HEIC -
image/heic
- HEIF -
image/heif
이미지에 관한 기술 세부정보
- 파일 한도: Gemini 2.5 Pro, 2.0 Flash, 1.5 Pro, 1.5 Flash는 요청당 최대 3,600개의 이미지 파일을 지원합니다.
- 토큰 계산:
- Gemini 1.5 Flash 및 Gemini 1.5 Pro: 두 크기가 모두 384픽셀 이하인 경우 258개 토큰 큰 이미지는 타일로 표시되며 (최소 타일 256px, 최대 768px, 768x768로 크기 조정) 각 타일은 258개의 토큰이 소요됩니다.
- Gemini 2.0 Flash: 두 측정기준이 모두 384픽셀 이하인 경우 258개 토큰 더 큰 이미지는 768x768픽셀 타일로 타일링되며, 각각 258개의 토큰이 소요됩니다.
- 권장사항:
- 이미지가 올바르게 회전되었는지 확인합니다.
- 선명하고 흐릿하지 않은 이미지를 사용하세요.
- 텍스트가 포함된 단일 이미지를 사용하는 경우
contents
배열의 이미지 부분 뒤에 텍스트 프롬프트를 배치합니다.
다음 단계
이 가이드에서는 이미지 파일을 업로드하고 이미지 입력에서 텍스트 출력을 생성하는 방법을 보여줍니다. 자세한 내용은 다음 리소스를 참고하세요.
- 시스템 안내: 시스템 안내를 사용하면 특정 요구사항 및 사용 사례에 따라 모델의 동작을 조정할 수 있습니다.
- 동영상 이해: 동영상 입력을 사용하는 방법을 알아봅니다.
- Files API: Gemini에서 사용할 파일을 업로드하고 관리하는 방법을 자세히 알아보세요.
- 파일 프롬프트 전략: Gemini API는 텍스트, 이미지, 오디오, 동영상 데이터를 사용한 프롬프트(다중 모달 프롬프트라고도 함)를 지원합니다.
- 안전 가이드: 생성형 AI 모델이 부정확하거나 편향되거나 불쾌감을 주는 출력과 같이 예상치 못한 출력을 생성하는 경우가 있습니다. 이러한 출력으로 인한 피해 위험을 제한하려면 후처리 및 사람의 평가가 필수적입니다.