Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion genai/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.24.0

require (
github.com/GoogleCloudPlatform/golang-samples v0.0.0-20250201051611-5fb145d1e974
google.golang.org/genai v1.17.0
google.golang.org/genai v1.25.0
)

require (
Expand Down
4 changes: 2 additions & 2 deletions genai/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
google.golang.org/api v0.217.0 h1:GYrUtD289o4zl1AhiTZL0jvQGa2RDLyC+kX1N/lfGOU=
google.golang.org/api v0.217.0/go.mod h1:qMc2E8cBAbQlRypBTBWHklNJlaZZJBwDv81B1Iu8oSI=
google.golang.org/genai v1.17.0 h1:lXYSnWShPYjxTouxRj0zF8RsNmSF+SKo7SQ7dM35NlI=
google.golang.org/genai v1.17.0/go.mod h1:QPj5NGJw+3wEOHg+PrsWwJKvG6UC84ex5FR7qAYsN/M=
google.golang.org/genai v1.25.0 h1:Cpyh2nmEoOS1eM3mT9XKuA/qWTEDoktfP2gsN3EduPE=
google.golang.org/genai v1.25.0/go.mod h1:OClfdf+r5aaD+sCd4aUSkPzJItmg2wD/WON9lQnRPaY=
google.golang.org/genproto v0.0.0-20250115164207-1a7da9e5054f h1:387Y+JbxF52bmesc8kq1NyYIp33dnxCw6eiA7JMsTmw=
google.golang.org/genproto v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:0joYwWwLQh18AOj8zMYeZLjzuqcYTU3/nC5JdCvC3JI=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA=
Expand Down
71 changes: 71 additions & 0 deletions genai/image_generation/image_generation_examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package image_generation

import (
"bytes"
"testing"

"github.com/GoogleCloudPlatform/golang-samples/internal/testutil"
)

func TestImageGeneration(t *testing.T) {
tc := testutil.SystemTest(t)

t.Setenv("GOOGLE_GENAI_USE_VERTEXAI", "1")
t.Setenv("GOOGLE_CLOUD_LOCATION", "global")
t.Setenv("GOOGLE_CLOUD_PROJECT", tc.ProjectID)

buf := new(bytes.Buffer)

t.Run("generate mmflash locale aware image content with text", func(t *testing.T) {
buf.Reset()
err := generateMMFlashLocaleAwareWithText(buf)
if err != nil {
t.Fatalf("generateMMFlashLocaleAwareWithText failed: %v", err)
}

output := buf.String()
if output == "" {
t.Error("expected non-empty output, got empty")
}
})

t.Run("generate mmflash multiple images with text", func(t *testing.T) {
buf.Reset()
err := generateMMFlashMultipleImgsWithText(buf)
if err != nil {
t.Fatalf("generateMMFlashMultipleImgsWithText failed: %v", err)
}

output := buf.String()
if output == "" {
t.Error("expected non-empty output, got empty")
}
})

t.Run("virtual try-on generation", func(t *testing.T) {
buf.Reset()
err := generateImgVirtualTryOnWithTextImg(buf)
if err != nil {
t.Fatalf("generateImgVirtualTryOnWithTextImg failed: %v", err)
}

output := buf.String()
if output == "" {
t.Error("expected non-empty output, got empty")
}
})
}
89 changes: 89 additions & 0 deletions genai/image_generation/imggen_mmflash_locale_aware_with_txt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package image_generation shows how to use the GenAI SDK to generate images and text.
package image_generation

// [START googlegenaisdk_imggen_mmflash_locale_aware_with_txt]
import (
"context"
"fmt"
"io"
"os"
"path/filepath"

"google.golang.org/genai"
)

// generateMMFlashLocaleAwareWithText demonstrates how to generate an image with locale awareness.
func generateMMFlashLocaleAwareWithText(w io.Writer) error {
ctx := context.Background()

client, err := genai.NewClient(ctx, &genai.ClientConfig{
HTTPOptions: genai.HTTPOptions{APIVersion: "v1"},
})
if err != nil {
return fmt.Errorf("failed to create genai client: %w", err)
}

modelName := "gemini-2.5-flash-image"
prompt := "Generate a photo of a breakfast meal."
contents := []*genai.Content{
{
Parts: []*genai.Part{
{Text: prompt},
},
Role: "user",
},
}

resp, err := client.Models.GenerateContent(ctx,
modelName,
contents,
&genai.GenerateContentConfig{
ResponseModalities: []string{
string(genai.ModalityText),
string(genai.ModalityImage),
},
},
)
if err != nil {
return fmt.Errorf("generate content failed: %w", err)
}

if len(resp.Candidates) == 0 || resp.Candidates[0].Content == nil {
return fmt.Errorf("no content was generated")
}

outputPath := filepath.Join("testdata", "example-breakfast-meal.png")

for _, part := range resp.Candidates[0].Content.Parts {
switch {
case part.Text != "":
fmt.Fprintln(w, part.Text)
case part.InlineData != nil:
if err := os.WriteFile(outputPath, part.InlineData.Data, 0o644); err != nil {
return fmt.Errorf("failed to save generated image: %w", err)
}
}
}
fmt.Fprintln(w, outputPath)

// Example response:
// Here is a photo of a delicious breakfast meal for you! ...

return nil
}

// [END googlegenaisdk_imggen_mmflash_locale_aware_with_txt]
102 changes: 102 additions & 0 deletions genai/image_generation/imggen_mmflash_multiple_imgs_with_txt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package image_generation shows how to use the GenAI SDK to generate images and text.
package image_generation

// [START googlegenaisdk_imggen_mmflash_multiple_imgs_with_txt]
import (
"context"
"fmt"
"io"
"os"
"path/filepath"

"google.golang.org/genai"
)

// generateMMFlashMultipleImgsWithText demonstrates how to generate multiple images with text.
func generateMMFlashMultipleImgsWithText(w io.Writer) error {
ctx := context.Background()

client, err := genai.NewClient(ctx, &genai.ClientConfig{
HTTPOptions: genai.HTTPOptions{APIVersion: "v1"},
})
if err != nil {
return fmt.Errorf("failed to create genai client: %w", err)
}

modelName := "gemini-2.5-flash-image"
prompt := "Generate 3 images a cat sitting on a chair."
contents := []*genai.Content{
{
Parts: []*genai.Part{
{Text: prompt},
},
Role: "user",
},
}

resp, err := client.Models.GenerateContent(ctx,
modelName,
contents,
&genai.GenerateContentConfig{
ResponseModalities: []string{
string(genai.ModalityText),
string(genai.ModalityImage),
},
},
)
if err != nil {
return fmt.Errorf("generate content failed: %w", err)
}

if len(resp.Candidates) == 0 || resp.Candidates[0].Content == nil {
return fmt.Errorf("no content was generated")
}

outputDir := filepath.Join("testdata")

imageCounter := 1
for _, part := range resp.Candidates[0].Content.Parts {
switch {
case part.Text != "":
fmt.Fprintln(w, part.Text)
case part.InlineData != nil:
filename := filepath.Join(outputDir, fmt.Sprintf("example-cats-0%d.png", imageCounter))
if err := os.WriteFile(filename, part.InlineData.Data, 0o644); err != nil {
return fmt.Errorf("failed to save generated image: %w", err)
}
fmt.Fprintln(w, filename)
imageCounter++
}
}

// Example response:
// Image 1: A fluffy calico cat with striking green eyes is perched elegantly on a vintage wooden
// chair with a woven seat. Sunlight streams through a nearby window, casting soft shadows and
// highlighting the cat's fur.
// #
// Image 2: A sleek black cat with intense yellow eyes is sitting upright on a modern, minimalist
// white chair. The background is a plain grey wall, putting the focus entirely on the feline's
// graceful posture.
// #
// Image 3: A ginger tabby cat with playful amber eyes is comfortably curled up asleep on a plush,
// oversized armchair upholstered in a soft, floral fabric. A corner of a cozy living room with a
// warm lamp in the background can be seen.

return nil
}

// [END googlegenaisdk_imggen_mmflash_multiple_imgs_with_txt]
100 changes: 100 additions & 0 deletions genai/image_generation/imggen_virtual_try_on_with_txt_img.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package image_generation shows how to use the GenAI SDK to generate images and text.
package image_generation

// [START googlegenaisdk_imggen_virtual_try_on_with_txt_img]
import (
"context"
"fmt"
"io"
"os"
"path/filepath"

"google.golang.org/genai"
)

// generateImgVirtualTryOnWithTextImg demonstrates how to apply a product image to a person image.
func generateImgVirtualTryOnWithTextImg(w io.Writer) error {
ctx := context.Background()

client, err := genai.NewClient(ctx, &genai.ClientConfig{
HTTPOptions: genai.HTTPOptions{APIVersion: "v1"},
})
if err != nil {
return fmt.Errorf("failed to create genai client: %w", err)
}

modelName := "virtual-try-on-preview-08-04"

// Load local person image
personBytes, err := os.ReadFile("testdata/man.png")
if err != nil {
return fmt.Errorf("failed to read person image: %w", err)
}
personImage := &genai.Image{
ImageBytes: personBytes,
MIMEType: "image/png",
}

// Load local product image
productBytes, err := os.ReadFile("testdata/sweater.jpg")
if err != nil {
return fmt.Errorf("failed to read product image: %w", err)
}
productImage := &genai.ProductImage{
ProductImage: &genai.Image{
ImageBytes: productBytes,
MIMEType: "image/jpeg",
},
}

resp, err := client.Models.RecontextImage(ctx,
modelName,
&genai.RecontextImageSource{
PersonImage: personImage,
ProductImages: []*genai.ProductImage{productImage},
}, nil,
)
if err != nil {
return fmt.Errorf("recontext image failed: %w", err)
}

// Ensure we have a generated image and save it
if len(resp.GeneratedImages) == 0 || resp.GeneratedImages[0].Image == nil {
return fmt.Errorf("no image was generated")
}

// TODO(developer): Update below lines
path := "testdata"
outputFile := "man_in_sweater.png"

// Save output
outputPath := filepath.Join(path, outputFile)

if err := os.WriteFile(outputPath, resp.GeneratedImages[0].Image.ImageBytes, 0o644); err != nil {
return fmt.Errorf("failed to save generated image: %w", err)
}

fmt.Fprintf(w, "Created output image using %d bytes\n", len(resp.GeneratedImages[0].Image.ImageBytes))
fmt.Fprintln(w, outputPath)

// Example response:
// Created output image using 1636301 bytes ...

return nil
}

// [END googlegenaisdk_imggen_virtual_try_on_with_txt_img]
Binary file added genai/image_generation/testdata/man.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added genai/image_generation/testdata/sweater.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading