Skip to content

Commit f0105e1

Browse files
jdomingrJuan Dominguez
andauthored
feat(genai): add image generation samples (2) (#3282)
Add new image generation samples - Edit image with text input and image input. - Generate image and text content with text input. **All local tests have passed** --------- Co-authored-by: Juan Dominguez <jdomin@softserveinc.com>
1 parent b982b20 commit f0105e1

File tree

5 files changed

+238
-0
lines changed

5 files changed

+238
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System.IO;
18+
using System.Threading.Tasks;
19+
using Xunit;
20+
21+
[Collection(nameof(GenAIFixture))]
22+
public class ImageGenMultimodalFlashEditImgWithTxtImgTest
23+
{
24+
private readonly GenAIFixture _fixture;
25+
private readonly ImageGenMultimodalFlashEditImgWithTxtImg _sample;
26+
27+
public ImageGenMultimodalFlashEditImgWithTxtImgTest(GenAIFixture fixture)
28+
{
29+
_fixture = fixture;
30+
_sample = new ImageGenMultimodalFlashEditImgWithTxtImg();
31+
}
32+
33+
[Fact]
34+
public async Task TestImageGenMultimodalFlashEditImgWithTxtImg()
35+
{
36+
string imageFilePath = Path.GetFullPath("../../../Resources/example-image-eiffel-tower.png");
37+
FileInfo response = await _sample.GenerateContent(projectId: _fixture.ProjectId, localImageFilePath: imageFilePath);
38+
Assert.NotNull(response);
39+
Assert.True(response.Length > 0);
40+
}
41+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System.IO;
18+
using System.Threading.Tasks;
19+
using Xunit;
20+
21+
[Collection(nameof(GenAIFixture))]
22+
public class ImageGenMultimodalMmFlashTxtAndImgWithTxtTest
23+
{
24+
private readonly GenAIFixture _fixture;
25+
private readonly ImageGenMultimodalFlashTxtAndImgWithTxt _sample;
26+
27+
public ImageGenMultimodalMmFlashTxtAndImgWithTxtTest(GenAIFixture fixture)
28+
{
29+
_fixture = fixture;
30+
_sample = new ImageGenMultimodalFlashTxtAndImgWithTxt();
31+
}
32+
33+
[Fact]
34+
public async Task TestImageGenMultimodalFlashTxtAndImgWithTxt()
35+
{
36+
FileInfo response = await _sample.GenerateContent(_fixture.ProjectId);
37+
Assert.NotNull(response);
38+
Assert.True(response.Length > 0);
39+
}
40+
}
1.92 MB
Loading
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
// [START googlegenaisdk_imggen_mmflash_edit_img_with_txt_img]
18+
19+
using Google.GenAI;
20+
using Google.GenAI.Types;
21+
using System;
22+
using System.Collections.Generic;
23+
using System.IO;
24+
using System.Threading.Tasks;
25+
26+
public class ImageGenMultimodalFlashEditImgWithTxtImg
27+
{
28+
public async Task<FileInfo> GenerateContent(
29+
string projectId = "your-project-id",
30+
string location = "global",
31+
string model = "gemini-2.5-flash-image",
32+
string localImageFilePath = "path/to/local_image.png")
33+
{
34+
await using var client = new Client(project: projectId, location: location, vertexAI: true);
35+
36+
byte[] imageBytes = File.ReadAllBytes(localImageFilePath);
37+
38+
GenerateContentResponse response = await client.Models.GenerateContentAsync(
39+
model: model,
40+
contents: new List<Content>
41+
{
42+
new Content
43+
{
44+
Role= "user",
45+
Parts = new List<Part>
46+
{
47+
new Part { InlineData = new Blob { Data = imageBytes, MimeType = "image/png" } },
48+
new Part { Text = "Edit this image to make it look like a cartoon."}
49+
}
50+
}
51+
},
52+
config: new GenerateContentConfig { ResponseModalities = new List<string> { "TEXT", "IMAGE" } });
53+
54+
List<Part> parts = response.Candidates?[0]?.Content?.Parts ?? new List<Part>();
55+
56+
var outputFilename = "bw-example-image.png";
57+
58+
foreach (Part part in parts)
59+
{
60+
if (!string.IsNullOrEmpty(part.Text))
61+
{
62+
Console.WriteLine(part.Text);
63+
}
64+
else if (part.InlineData?.Data != null)
65+
{
66+
File.WriteAllBytes(outputFilename, part.InlineData.Data);
67+
}
68+
}
69+
70+
FileInfo fileInfo = new FileInfo(Path.GetFullPath(outputFilename));
71+
Console.WriteLine($"Created output image using {fileInfo.Length} bytes");
72+
// Example response:
73+
// Here's the image cartoonized for you!
74+
// Created output image using 1628165 bytes
75+
return fileInfo;
76+
}
77+
}
78+
// [END googlegenaisdk_imggen_mmflash_edit_img_with_txt_img]
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
// [START googlegenaisdk_imggen_mmflash_txt_and_img_with_txt]
18+
19+
using Google.GenAI;
20+
using Google.GenAI.Types;
21+
using System;
22+
using System.Collections.Generic;
23+
using System.IO;
24+
using System.Threading.Tasks;
25+
26+
public class ImageGenMultimodalFlashTxtAndImgWithTxt
27+
{
28+
public async Task<FileInfo> GenerateContent(
29+
string projectId = "your-project-id",
30+
string location = "global",
31+
string model = "gemini-2.5-flash-image")
32+
{
33+
await using var client = new Client(project: projectId, location: location, vertexAI: true);
34+
35+
GenerateContentResponse response = await client.Models.GenerateContentAsync(
36+
model: model,
37+
contents: new List<Content>
38+
{
39+
new Content
40+
{
41+
Role= "user",
42+
Parts = new List<Part>
43+
{
44+
new Part { Text = "Generate an illustrated recipe for a paella." },
45+
new Part { Text = "Create images to go alongside the text as you generate the recipe."}
46+
}
47+
}
48+
},
49+
config: new GenerateContentConfig { ResponseModalities = new List<string> { "TEXT", "IMAGE" } });
50+
51+
List<Part> parts = response.Candidates?[0]?.Content?.Parts ?? new List<Part>();
52+
53+
using (StreamWriter writer = new StreamWriter("paella-recipe.md"))
54+
{
55+
int imageCounter = 1;
56+
foreach (Part part in parts)
57+
{
58+
if (!string.IsNullOrEmpty(part.Text))
59+
{
60+
writer.WriteLine(part.Text);
61+
}
62+
else if (part.InlineData?.Data != null)
63+
{
64+
string filename = $"example-image-{imageCounter}.png";
65+
File.WriteAllBytes(filename, part.InlineData.Data);
66+
writer.WriteLine($"\n![image]({filename})\n");
67+
imageCounter++;
68+
}
69+
}
70+
}
71+
72+
FileInfo fileInfo = new FileInfo(Path.GetFullPath("paella-recipe.md"));
73+
Console.WriteLine($"Created output image using {fileInfo.Length} bytes");
74+
// Example response:
75+
// Created output image using 2329 bytes
76+
return fileInfo;
77+
}
78+
}
79+
// [END googlegenaisdk_imggen_mmflash_txt_and_img_with_txt]

0 commit comments

Comments
 (0)