
Компания Google выпустила Gemini 2.0 Flash со встроенными возможностями редактирования изображений, и это одна из самых революционных моделей, выпущенных Google в этом году. Я немного необъективен, потому что меня очень интересуют модели изображений с тех пор, как я запустил свое веб-приложение для генерации изображений.
Известно, что технологический гигант плохо разбирается в документации по API, поэтому последние несколько дней я испытывал трудности с интеграцией Gemini 2.0 Flash в Flux Labs. К счастью, Логан Килпатрик, ведущий инженер по продуктам Google AI Studio, недавно опубликовал обновленную документацию, которая значительно облегчает работу.
Так что если вы планируете создавать приложения с нуля или интегрировать Gemini 2.0 Flash в существующее веб-приложение, то сейчас я расскажу вам, как это сделать.
Что нового в Gemini 2.0 Flash?
Gemini 2.0 Flash от Google теперь поддерживает редактирование изображений с помощью промптов на естественном языке. В отличие от предыдущих мультимодальных систем, которые использовали отдельные модели (например, объединяли языковую модель с Imagen 3 для генерации изображений), Gemini 2.0 Flash обрабатывает и текст, и изображения в рамках одной единой системы.
Такой единый подход устраняет необходимость в межмодельном взаимодействии и значительно сокращает время ожидания. Кроме того, теперь она поддерживает добавление длинного текста непосредственно на изображения.
Если вы еще не опробовали новые возможности Gemini 2.0 по редактированию изображений, я очень советую сначала поэкспериментировать с ними в Google AI Studio, прежде чем создавать приложение-обертку или интегрировать его в существующее веб-приложение.
Вот краткий обзор AI Studio. Убедитесь, что выбрали модель «Gemini 2.0 Flash Experimental» и установили формат вывода «Images and text».

Потратьте время, чтобы в полной мере оценить новые возможности. Как только освоитесь, приступайте к пошаговой интеграции с использованием API.
Сначала создайте пользовательский интерфейс
Прежде чем перейти к вызовам API, убедитесь, что у вас есть работающий фронтенд. Вы можете начать с нуля или добавить специальную тестовую страницу в ваше текущее веб-приложение. В моем случае я создал страницу «Image Manipulator» на Flux Labs AI с возможностью загрузить изображение слева, окном промпта под ним и предварительным просмотром полученного изображения справа.

Итак, когда все готово, пора заняться бэкэндом.
Генерация ключа API
Первое, что вам понадобится для доступа к API Gemini, - это ключ API. Перейдите в Google AI Studio и нажмите на кнопку «Get API key».

Затем нажмите на кнопку «Create API key», чтобы сгенерировать секретный ключ. Убедитесь, что этот ключ защищен и является приватным.
Далее создайте переменную окружения с именем GEMINI_API_KEY и укажите в качестве ее значения ключ API, полученный от Google AI Studio.
Где находится API?
Документация Google по API представляет собой беспорядочный набор документов. Трудно найти нужный пример API для конкретной модели. Чтобы избавить вас от головной боли, вот прямая ссылка на раздел «Редактирование изображений с помощью Gemini».

Вот пример кода:
const { GoogleGenerativeAI } = require("@google/generative-ai");
const fs = require("fs");
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function generateImage() {
// Load the image from the local file system
const imagePath = '/path/to/image.png';
const imageData = fs.readFileSync(imagePath);
const base64Image = imageData.toString('base64');
// Prepare the content parts
const contents = [
{ text: "Hi, This is a picture of me. Can you add a llama next to me?" },
{
inlineData: {
mimeType: 'image/png',
data: base64Image
}
}
];
// Set responseModalities to include "Image" so the model can generate an image
const model = genAI.getGenerativeModel({
model: "gemini-2.0-flash-exp-image-generation",
generationConfig: {
responseModalities: ['Text', 'Image']
},
});
try {
const response = await model.generateContent(contents);
for (const part of response.response.candidates[0].content.parts) {
// Based on the part type, either show the text or save the image
if (part.text) {
console.log(part.text);
} else if (part.inlineData) {
const imageData = part.inlineData.data;
const buffer = Buffer.from(imageData, 'base64');
fs.writeFileSync('gemini-native-image.png', buffer);
console.log('Image saved as gemini-native-image.png');
}
}
} catch (error) {
console.error("Error generating content:", error);
}
}
generateImage();
Скопируйте этот фрагмент кода, вернитесь в IDE Cursor и попросите его реализовать вызов API к Gemini 2.0 Flash.
Если у вас возникнут проблемы (как у меня), вы можете посетить пример проекта NextJS, размещенного Google на GitHub, и скопировать пример кода, расположенный в ~/app/api/image/route.ts.

Вот полный текст примера:
import { NextRequest, NextResponse } from "next/server";
import { GoogleGenerativeAI } from "@google/generative-ai";
import { HistoryItem, HistoryPart } from "@/lib/types";
// Initialize the Google Gen AI client with your API key
const GEMINI_API_KEY = process.env.GEMINI_API_KEY || "";
const genAI = new GoogleGenerativeAI(GEMINI_API_KEY);
// Define the model ID for Gemini 2.0 Flash experimental
const MODEL_ID = "gemini-2.0-flash-exp";
// Define interface for the formatted history item
interface FormattedHistoryItem {
role: "user" | "model";
parts: Array<{text?: string; inlineData?: { data: string; mimeType: string };}>;
}
export async function POST(req: NextRequest) {
try {
// Parse JSON request instead of FormData
const requestData = await req.json();
const { prompt, image: inputImage, history } = requestData;
if (!prompt) {
return NextResponse.json( { error: "Prompt is required" }, { status: 400 });
}
// Get the model with the correct configuration
const model = genAI.getGenerativeModel({
model: MODEL_ID,
generationConfig: {
temperature: 1, topP: 0.95, topK: 40,
// @ts-expect-error - Gemini API JS is missing this type
responseModalities: ["Text", "Image"],
},
});
let result;
try {
// Convert history to the format expected by Gemini API
const formattedHistory =
history && history.length > 0
? history
.map((item: HistoryItem) => {
return {
role: item.role, parts: item.parts
.map((part: HistoryPart) => {
if (part.text) { return { text: part.text }; }
if (part.image && item.role === "user") {
const imgParts = part.image.split(",");
if (imgParts.length > 1) {
return { inlineData: { data: imgParts[1], mimeType: part.image.includes("image/png") ? "image/png" : "image/jpeg", }, }; } }
return { text: "" };
}) .filter((part) => Object.keys(part).length > 0), // Remove empty parts
};
}) .filter((item: FormattedHistoryItem) => item.parts.length > 0) // Remove items with no parts
: [];
// Create a chat session with the formatted history
const chat = model.startChat({
history: formattedHistory,
});
// Prepare the current message parts
const messageParts = [];
// Add the text prompt
messageParts.push({ text: prompt });
// Add the image if provided
if (inputImage) {
// For image editing
console.log("Processing image edit request");
const imageParts = inputImage.split(",");
if (imageParts.length < 2) {
throw new Error("Invalid image data URL format");
}
const base64Image = imageParts[1];
const mimeType = inputImage.includes("image/png")? "image/png": "image/jpeg";
// Add the image to message parts
messageParts.push({
inlineData: { data: base64Image, mimeType: mimeType,},});
}
// Send the message to the chat
console.log("Sending message with", messageParts.length, "parts");
result = await chat.sendMessage(messageParts);
} catch (error) {
console.error("Error in chat.sendMessage:", error);
throw error;
}
const response = result.response;
let textResponse = null;
let imageData = null;
let mimeType = "image/png";
// Process the response
if (response.candidates && response.candidates.length > 0) {
const parts = response.candidates[0].content.parts;
console.log("Number of parts in response:", parts.length);
for (const part of parts) {
if ("inlineData" in part && part.inlineData) {
// Get the image data
imageData = part.inlineData.data;
mimeType = part.inlineData.mimeType || "image/png";
} else if ("text" in part && part.text) {
// Store the text
textResponse = part.text;
}
}
}
// Return just the base64 image and description as JSON
return NextResponse.json({
image: imageData ? `data:${mimeType};base64,${imageData}` : null, description: textResponse,
});
} catch (error) {
// rest of the code
}
}
Эта конечная точка API взаимодействует с искусственным интеллектом Gemini 2.0 Flash от Google, обрабатывая пользовательские данные и генерируя ответ в виде текста или изображения. Она проверяет входящие запросы, форматирует историю прошлых разговоров для определения контекста и отправляет обработанные данные в Gemini AI.
Модель возвращает ответ, который API анализирует для извлечения текстовых данных или изображений в кодировке base64. Наконец, в качестве ответа выдается объект JSON, содержащий сгенерированный текст или изображение. Конечная точка поддерживает мультимодальный ввод, сохраняет историю чата и включает обработку ошибок для повышения надежности.
Скопируйте этот пример кода в Cursor AI и попросите его соответствующим образом реализовать интеграцию с бэкендом. В случае успеха у вас должны получиться такие результаты:
Промпт: Make the seal wear a party hat

Великолепно. Честно говоря, мне нравится, как Gemini сохраняет исходное изображение в основном без изменений, редактируя только нужные части. И, кстати, это изображение тюленя создано с помощью Imagen 3.
Работа с несколькими изображениями
Еще один классный трюк, который вы можете проделать с Gemini 2.0 Flash при помощи встроенной генерации изображений, - это использовать его возможности для одновременной работы с несколькими исходными изображениями.
Обновите свой внешний интерфейс, чтобы пользователи могли загружать несколько изображений одновременно. Например, дайте команду Cursor AI сделать поддержку загрузки до четырех изображений одновременно и организуйте секцию предварительного просмотра в виде аккуратной сетки 2x2.

Точное количество поддерживаемых изображений не указано в документации, но я выбрал четыре, чтобы избежать чрезмерного использования токенов. Затем Gemini объединяет все предоставленные изображения в соответствии с инструкциями в промпте.
Например, вы можете загрузить изображение модели-мужчины и изображение товара, а затем попросить Gemini:
Промпт: Make the man hold the perfume

Это очень круто, правда?
Чтобы это сделать, вы можете обратиться к этой документации по исходным изображениям, а ниже приведен пример запроса для работы с несколькими изображениями в кодировке Base64.
import { GoogleGenerativeAI } from "@google/generative-ai";
// Access your API key as an environment variable (see "Set up your API key" above)
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
const model = genAI.getGenerativeModel({ model: 'models/gemini-1.5-pro' });
const imageResp1 = await fetch(IMAGE_PATH_1).then((response) => response.arrayBuffer());
const imageResp2 = await fetch(IMAGE_PATH_2).then((response) => response.arrayBuffer());
const result = await model.generateContent([
{
inlineData: {
data: Buffer.from(imageResp1).toString("base64"),
mimeType: "image/jpeg",
},
},
{
inlineData: {
data: Buffer.from(imageResp2).toString("base64"),
mimeType: "image/jpeg",
},
},
'Generate a list of all the objects contained in both images.',
]);
console.log(result.response.text());
Скопируйте этот скрипт и попросите Cursor реализовать возможность загрузки нескольких изображений.
the image manipulator should support multiple image inputs. can you support it? [ ВСТАВЬТЕ СЮДА API СКРИПТ ]
После успешной интеграции в вашем веб-приложении можно будет легко работать с изображениями или даже объединять несколько изображений.
Сколько стоит API?
Теперь давайте поговорим о ценах. Структура цен делится на бесплатные и платные варианты.
-
На бесплатной подписке пользователи могут делиться текстом, изображениями, видео или аудио без какой-либо оплаты. Результаты также бесплатны, и вы бесплатно получаете контекстное кэширование, которое позволяет хранить до 1 000 000 токенов каждый час. Кроме того, вы можете использовать Google Search для создания базы данных без какой-либо оплаты в объеме до 500 запросов в день.
-
Когда вы переходите на платную подписку, то в зависимости от объема использования взимается определенная плата. За исходные данные придется заплатить 0,10 доллара за каждый 1 миллион токенов текста, изображения или видео, а за аудио - 0,70 доллара. Выходные данные стоят 0,40 доллара за 1 миллион токенов. Если вам нужно контекстное кэширование, то его стоимость составит 0,025 доллара за 1 миллион токенов для текста, изображения или видео и 0,175 доллара для аудио. Эти функции станут доступны начиная с 31 марта 2025 года.

Разница между подписками заключается в использовании данных: данные, обрабатываемые в бесплатной версии могут быть использованы для улучшения продуктов Google, в то время как данные в платной версии не используются для этих целей. Поэтому если вас волнует вопрос конфиденциальности данных, вам лучше не использовать бесплатную версию.
Вы можете спросить: сколько токенов содержится в одном изображении?
Все данные, поступающие в Gemini API, токенизируются, включая текст, файлы изображений и другие нетекстовые данные.
В Gemini 2.0 изображения с обоими размерами <=384 пикселей считаются за 258 токенов. Изображения, увеличенные в одном или обоих размерах, обрезаются и масштабируются по мере необходимости в плитки размером 768x768 пикселей, каждая из которых учитывается как 258 токенов.
Также рекомендую вам подписаться на Google Cloud Billing, чтобы вы могли отслеживать использование API. Удивительно, но я получил ~40 тысяч японских йен или 270 долларов США бесплатных кредитов после того, как подписался на нее.

Рекламные кредиты используются в качестве формы оплаты, чтобы уменьшить сумму вашего долга. К этой категории относятся кредиты на бесплатную пробную версию GCP и маркетинговые кампании. Перейдите на страницу Billing Credits, чтобы узнать подробности о ваших кредитах.
Несколько действительно классных вариантов использования
Я размышлял о некоторых действительно потрясающих вариантах использования Gemini 2.0 Flash, и вот некоторые из них:
-
Продуктовый маркетинг. Вы можете загрузить изображение модели и товара и попросить ИИ сделать так, чтобы модель держала товар. Я уже делал это в примере выше, и я думаю, что это очень важно для маркетологов и бизнесменов. Представьте, как быстро и легко можно создавать рекламные материалы.
-
Быстрое редактирование изображений. Возможность сохранять большинство частей исходного изображения и вносить изменения только в определенные фрагменты делает этот инструмент фотошопом на стероидах. Вы можете быстро заменить, удалить или даже стилизовать определенные части изображений, не затрагивая остальные.
-
Изображения для разработчиков игр. Я видел пользователей, использующих Gemini 2.0 Flash для создания изображений и спрайтов для своих игр. Просто загрузите одно эталонное изображение и попросите ИИ создать несколько его вариантов. Это очень удобно, особенно для инди-разработчиков, которым нужны быстрые итерации.
-
Нет необходимости в тонкой настройке. Знаете ли вы, что для создания изображений с вами больше не нужно настраивать модель для генерации изображений? Просто загрузите свой портрет и попросите ИИ создать другое изображение в другом стиле или окружении. Это очень важно для приложений для создания ИИ-портретов.
Gemini 2.0 Flash с встроенной функцией редактирования изображений - одна из лучших ИИ-моделей для работы с изображениями на основе инструкций, доступных прямо сейчас. Я тестировал ее несколько дней, и то, как она редактирует изображения на основе пользовательских инструкций, просто на порядок превосходит другие модели. Она не самая быстрая, и она не создает абсолютно лучшие по качеству изображения, но когда дело доходит до точных, контекстно-зависимых правок, ничто другое и близко не подходит.
Возможности становятся еще шире, если объединить его с другими ИИ-моделями, такими как Veo 2 для создания видео или Flux 1.1 Pro Ultra для обработки изображений. Как разработчику, мне хочется создавать новые приложения и экспериментировать с уникальными вариантами использования, потому что потенциал просто огромен.
Если вы еще не пробовали экспериментальный Gemini 2.0 Flash, попробуйте его в Google AI Studio. А если вы уже используете ИИ-модели для генерации изображений, то эту обязательно стоит протестировать, чтобы узнать, не превосходит ли она то, что вы используете сейчас.
Друзья, буду рад, если вы подпишетесь на мой телеграм-канал про нейросети, чтобы не пропускать анонсы статей, и про генерацию изображений - я стараюсь делиться только полезной информацией.
Автор: NeyroEntuziast