Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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-preview"
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-preview"
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