{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "BCl9pcbOOeA0"
      },
      "outputs": [],
      "source": [
        "# Copyright 2025 Google LLC\n",
        "#\n",
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "#     https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZPC2X_a9ErW7"
      },
      "source": [
        "# Gemini 2.0 Flash Image Generation in Vertex AI\n",
        "\n",
        "<table align=\"left\">\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/getting-started/intro_gemini_2_0_image_gen.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fgetting-started%2Fintro_gemini_2_0_image_gen.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/getting-started/intro_gemini_2_0_image_gen.ipynb\">\n",
        "      <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/getting-started/intro_gemini_2_0_image_gen.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
        "    </a>\n",
        "  </td>\n",
        "</table>\n",
        "\n",
        "<div style=\"clear: both;\"></div>\n",
        "\n",
        "<b>Share to:</b>\n",
        "\n",
        "<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/getting-started/intro_gemini_2_0_image_gen.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/getting-started/intro_gemini_2_0_image_gen.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/getting-started/intro_gemini_2_0_image_gen.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/getting-started/intro_gemini_2_0_image_gen.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/getting-started/intro_gemini_2_0_image_gen.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
        "</a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f0cc0f48513b"
      },
      "source": [
        "| Authors |\n",
        "| --- |\n",
        "| [Nikita Namjoshi](https://github.com/nikitamaia) |\n",
        "| [Katie Nguyen](https://github.com/katiemn) |"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "axauUzNXEl_R"
      },
      "source": [
        "## Overview\n",
        "\n",
        "Gemini 2.0 Flash supports image generation and editing. This enables you to converse with Gemini and create images with interwoven text.\n",
        "\n",
        "In this tutorial, you learn how to use Gemini 2.0 Flash image generation features in Vertex AI using the Google Gen AI SDK.\n",
        "\n",
        "You'll try out the following scenarios:\n",
        "* Image generation:\n",
        "  * Text to image\n",
        "  * Text to image and text (interleaved)\n",
        "* Image editing:\n",
        "  * Text and image to image\n",
        "  * Multi-turn image editing\n",
        "  * Images and text to image and text (interleaved)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "D50ekWXjEl_S"
      },
      "source": [
        "## Get started"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jLJQdbgSbb4M"
      },
      "source": [
        "### Install Google Gen AI SDK for Python"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "SQ0qcEWuXNXs"
      },
      "outputs": [],
      "source": [
        "%pip install --upgrade --quiet google-genai"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dmWOrTJ3gx13"
      },
      "source": [
        "### Authenticate your notebook environment (Colab only)\n",
        "\n",
        "If you are running this notebook on Google Colab, run the following cell to authenticate your environment."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "NyKGtVQjgx13"
      },
      "outputs": [],
      "source": [
        "import sys\n",
        "\n",
        "if \"google.colab\" in sys.modules:\n",
        "    from google.colab import auth\n",
        "\n",
        "    auth.authenticate_user()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gfs2gxVrAN02"
      },
      "source": [
        "### Import libraries"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "bPd_HnO0AQmL"
      },
      "outputs": [],
      "source": [
        "from IPython.display import Image, Markdown, display\n",
        "from google import genai\n",
        "from google.genai.types import GenerateContentConfig, Part"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "O6ZGaZlxP9L0"
      },
      "source": [
        "### Set Google Cloud project information and create client\n",
        "\n",
        "To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
        "\n",
        "Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "u8IivOG5SqY6"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "\n",
        "PROJECT_ID = \"[your-project-id]\"  # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
        "if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
        "    PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
        "\n",
        "LOCATION = \"global\"\n",
        "\n",
        "client = genai.Client(vertexai=True, project=PROJECT_ID, location=LOCATION)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "854fbf388e2b"
      },
      "source": [
        "### Load the image model\n",
        "\n",
        "Gemini 2.0 Flash image generation: `gemini-2.0-flash-preview-image-generation`"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "7eeb063ac6d4"
      },
      "outputs": [],
      "source": [
        "MODEL_ID = \"gemini-2.0-flash-preview-image-generation\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xgOucVQlVR4t"
      },
      "source": [
        "## Image generation\n",
        "\n",
        "First, send a text prompt to Gemini 2.0 Flash describing the image you want to generate.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MmA_RAbFwED4"
      },
      "source": [
        "### Text to image\n",
        "\n",
        "In the cell below, you'll call the `generate_content` method and pass in the following arguments:\n",
        "\n",
        "* `model`: The ID of the model you want to use\n",
        "* `contents`: this is your prompt, in this case a text only user message describing the image to be generated\n",
        "*`config`: A config for specifying content settings\n",
        "  * `response_modalities`: in this case `TEXT` and `IMAGE`, if you do not specify `IMAGE`, you will not get image output and `IMAGE` only is not allowed\n",
        "  * `candidate_count`: the number of candidates to generate\n",
        "  * `safety_settings`:\n",
        "    * `method`: HARM_BLOCK_METHOD_UNSPECIFIED, SEVERITY, PROBABILITY\n",
        "    * `category`: HARM_CATEGORY_UNSPECIFIED, HARM_CATEGORY_HATE_SPEECH, HARM_CATEGORY_DANGEROUS_CONTENT, HARM_CATEGORY_HARASSMENT, HARM_CATEGORY_SEXUALLY_EXPLICIT, HARM_CATEGORY_CIVIC_INTEGRITY\n",
        "    * `threshold`: HARM_BLOCK_THRESHOLD_UNSPECIFIED, BLOCK_LOW_AND_ABOVE, BLOCK_MEDIUM_AND_ABOVE, BLOCK_ONLY_HIGH, BLOCK_NONE, OFF\n",
        "\n",
        "All generated images include a [SynthID watermark](https://deepmind.google/technologies/synthid/), which can be verified via the Media Studio in [Vertex AI Studio](https://cloud.google.com/generative-ai-studio?hl=en)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QK2Mi3zmkHSA"
      },
      "outputs": [],
      "source": [
        "response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=\"generate an image of a penguin driving a taxi in New York City\",\n",
        "    config=GenerateContentConfig(\n",
        "        response_modalities=[\"TEXT\", \"IMAGE\"],\n",
        "        candidate_count=1,\n",
        "        safety_settings=[\n",
        "            {\"method\": \"PROBABILITY\"},\n",
        "            {\"category\": \"HARM_CATEGORY_DANGEROUS_CONTENT\"},\n",
        "            {\"threshold\": \"BLOCK_MEDIUM_AND_ABOVE\"},\n",
        "        ],\n",
        "    ),\n",
        ")\n",
        "\n",
        "for part in response.candidates[0].content.parts:\n",
        "    if part.text:\n",
        "        display(Markdown(part.text))\n",
        "    if part.inline_data:\n",
        "        display(Image(data=part.inline_data.data, width=350, height=350))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5l4YLy8Vq_-v"
      },
      "source": [
        "### Text to image and text\n",
        "\n",
        "In addition to generating images, Gemini can generate multiple images and text in an interleaved fashion.\n",
        "\n",
        "For example, you could ask the model to generate a recipe for banana bread with images showing different stages of the cooking process. Or, you could ask the model to generate images of different wildflowers with accompanying titles and descriptions.\n",
        "\n",
        "Let's try out the interleaved text and image functionality by prompting Gemini 2.0 Flash to create a tutorial for assemblying a peanut butter and jelly sandwich.\n",
        "\n",
        "You'll notice that in the prompt we ask the model to generate both text and images for each episode of the narrative. This will nudge the model to create text with images interleaved."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WdkrXmyIFtgv"
      },
      "source": [
        "⚠️ **Note:** that we are asking the model to generate a lot of content in this prompt, so it will take a bit of time for this cell to finish executing."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "FwCeB0Hxlrz2"
      },
      "outputs": [],
      "source": [
        "response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=\"Create a tutorial explaining how to make a peanut butter and jelly sandwich in three easy steps. For each step, provide a title with the number of the step, an explanation, and also generate an image, generate each image in a 1:1 aspect ratio.\",\n",
        "    config=GenerateContentConfig(\n",
        "        response_modalities=[\"TEXT\", \"IMAGE\"],\n",
        "        safety_settings=[\n",
        "            {\"method\": \"PROBABILITY\"},\n",
        "            {\"category\": \"HARM_CATEGORY_DANGEROUS_CONTENT\"},\n",
        "            {\"threshold\": \"BLOCK_MEDIUM_AND_ABOVE\"},\n",
        "        ],\n",
        "    ),\n",
        ")\n",
        "\n",
        "for part in response.candidates[0].content.parts:\n",
        "    if part.text:\n",
        "        display(Markdown(part.text))\n",
        "    if part.inline_data:\n",
        "        display(Image(data=part.inline_data.data, width=350, height=350))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "R3g5n23lDtsN"
      },
      "source": [
        "## Image editing\n",
        "\n",
        "You can pass text and an image to Gemini 2.0 Flash for use cases like product captions, information about a particular image, or to make edits or modifications to an existing image.\n",
        "\n",
        "### Text and image to image\n",
        "\n",
        "Let's try out a style transfer example and ask Gemini 2.0 Flash to create an image of this dog in a 3D cartoon rendering.\n",
        "\n",
        "Run the next cell to visualize the starting dog image."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Bd9CASBlNc1p"
      },
      "outputs": [],
      "source": [
        "image_url = (\n",
        "    \"https://storage.googleapis.com/cloud-samples-data/generative-ai/image/dog-1.jpg\"\n",
        ")\n",
        "display(Image(url=image_url, width=350, height=350))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "UAiUyW1VMzPn"
      },
      "outputs": [],
      "source": [
        "response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=[\n",
        "        Part.from_uri(\n",
        "            file_uri=\"gs://cloud-samples-data/generative-ai/image/dog-1.jpg\",\n",
        "            mime_type=\"image/jpeg\",\n",
        "        ),\n",
        "        \"Create a 3D cartoon style portrait of this dog, include rounded, exaggerated facial features, saturated colors, and realistic-looking textures. The dog is wearing a cowboy hat.\",\n",
        "    ],\n",
        "    config=GenerateContentConfig(\n",
        "        response_modalities=[\"TEXT\", \"IMAGE\"],\n",
        "        candidate_count=1,\n",
        "        safety_settings=[\n",
        "            {\"method\": \"PROBABILITY\"},\n",
        "            {\"category\": \"HARM_CATEGORY_DANGEROUS_CONTENT\"},\n",
        "            {\"threshold\": \"BLOCK_MEDIUM_AND_ABOVE\"},\n",
        "        ],\n",
        "    ),\n",
        ")\n",
        "for part in response.candidates[0].content.parts:\n",
        "    if part.text:\n",
        "        display(Markdown(part.text))\n",
        "    if part.inline_data:\n",
        "        display(Image(data=part.inline_data.data, width=350, height=350))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2vnEO2OfPkjn"
      },
      "source": [
        "### Multi-turn image editing\n",
        "\n",
        "In this next section, you supply a starting image and iteratively alter certain aspects of the image though chatting with Gemini 2.0 Flash.\n",
        "\n",
        "\n",
        "Run the next step to view the starting image of a vase stored in Google Cloud Storage."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Aq_Y7ORJP1ni"
      },
      "outputs": [],
      "source": [
        "image_url = (\n",
        "    \"https://storage.googleapis.com/cloud-samples-data/generative-ai/image/vase.png\"\n",
        ")\n",
        "display(Image(url=image_url, width=350, height=350))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "B-2KXCNgQEYu"
      },
      "outputs": [],
      "source": [
        "chat = client.chats.create(model=MODEL_ID)\n",
        "\n",
        "response = chat.send_message(\n",
        "    message=[\n",
        "        Part.from_uri(\n",
        "            file_uri=\"gs://cloud-samples-data/generative-ai/image/vase.png\",\n",
        "            mime_type=\"image/png\",\n",
        "        ),\n",
        "        \"add sunflowers to this vase\",\n",
        "    ],\n",
        "    config=GenerateContentConfig(\n",
        "        response_modalities=[\"TEXT\", \"IMAGE\"],\n",
        "    ),\n",
        ")\n",
        "\n",
        "for part in response.candidates[0].content.parts:\n",
        "    if part.text:\n",
        "        display(Markdown(part.text))\n",
        "    if part.inline_data:\n",
        "        display(Image(data=part.inline_data.data, width=350, height=350))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Loi4drVpdCjn"
      },
      "source": [
        "Now, send a new text message to the existing chat asking to update the previously generated image."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "99B7me3HGC1I"
      },
      "outputs": [],
      "source": [
        "response = chat.send_message(\n",
        "    message=[\n",
        "        \"change the sunflowers in the vase to pink and purple tulips\",\n",
        "    ],\n",
        "    config=GenerateContentConfig(\n",
        "        response_modalities=[\"TEXT\", \"IMAGE\"],\n",
        "    ),\n",
        ")\n",
        "\n",
        "for part in response.candidates[0].content.parts:\n",
        "    if part.text:\n",
        "        display(Markdown(part.text))\n",
        "    if part.inline_data:\n",
        "        display(Image(data=part.inline_data.data, width=350, height=350))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1l19iG4CZMEr"
      },
      "source": [
        "### Images and text to image and text\n",
        "\n",
        "When editing images with Gemini 2.0 Flash, you can also supply multiple input images to create new ones. In this next example, you'll prompt Gemini with an image of a teacup and an outdoor table. You'll then ask Gemini to combine the objects from these images in order to create a new one. You'll also ask Gemini to supply text to accompany the image.\n",
        "\n",
        "\n",
        "Run the following cell to visualize the starting images of an outdoor table and teacup."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "HuLVkC3edP6s"
      },
      "outputs": [],
      "source": [
        "table_url = (\n",
        "    \"https://storage.googleapis.com/cloud-samples-data/generative-ai/image/table.png\"\n",
        ")\n",
        "display(Image(url=table_url, width=300, height=300))\n",
        "\n",
        "teacup_url = (\n",
        "    \"https://storage.googleapis.com/cloud-samples-data/generative-ai/image/teacup-1.png\"\n",
        ")\n",
        "display(Image(url=teacup_url, width=300, height=300))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "WD3XoWjuZQFr"
      },
      "outputs": [],
      "source": [
        "response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=[\n",
        "        Part.from_uri(\n",
        "            file_uri=\"gs://cloud-samples-data/generative-ai/image/table.png\",\n",
        "            mime_type=\"image/png\",\n",
        "        ),\n",
        "        Part.from_uri(\n",
        "            file_uri=\"gs://cloud-samples-data/generative-ai/image/teacup-1.png\",\n",
        "            mime_type=\"image/png\",\n",
        "        ),\n",
        "        \"Generate a side profile image of a person sitting at this table drinking out of this teacup in a 1:1 aspect ratio. Include a caption that could be used to post this image on social media.\",\n",
        "    ],\n",
        "    config=GenerateContentConfig(\n",
        "        response_modalities=[\"TEXT\", \"IMAGE\"],\n",
        "        candidate_count=1,\n",
        "        safety_settings=[\n",
        "            {\"method\": \"PROBABILITY\"},\n",
        "            {\"category\": \"HARM_CATEGORY_DANGEROUS_CONTENT\"},\n",
        "            {\"threshold\": \"BLOCK_MEDIUM_AND_ABOVE\"},\n",
        "        ],\n",
        "    ),\n",
        ")\n",
        "\n",
        "for part in response.candidates[0].content.parts:\n",
        "    if part.text:\n",
        "        display(Markdown(part.text))\n",
        "    if part.inline_data:\n",
        "        display(Image(data=part.inline_data.data, width=350, height=350))"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "intro_gemini_2_0_image_gen.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
