Skip to content

Commit 9b548b8

Browse files
authored
feat(genai): Add new samples for image editing (#13408)
1 parent b338544 commit 9b548b8

15 files changed

+332
-2
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from google.genai.types import Image
16+
17+
18+
def edit_inpainting_insert(output_file: str) -> Image:
19+
# [START googlegenaisdk_imggen_inpainting_insert_with_txt_img]
20+
from google import genai
21+
from google.genai.types import RawReferenceImage, MaskReferenceImage, MaskReferenceConfig, EditImageConfig
22+
23+
client = genai.Client()
24+
25+
# TODO(developer): Update and un-comment below line
26+
# output_file = "output-image.png"
27+
28+
raw_ref = RawReferenceImage(
29+
reference_image=Image.from_file(location='test_resources/fruit.png'), reference_id=0)
30+
mask_ref = MaskReferenceImage(
31+
reference_id=1,
32+
reference_image=None,
33+
config=MaskReferenceConfig(
34+
mask_mode="MASK_MODE_FOREGROUND",
35+
mask_dilation=0.1,
36+
),
37+
)
38+
39+
image = client.models.edit_image(
40+
model="imagen-3.0-capability-001",
41+
prompt="A small white ceramic bowl with lemons and limes",
42+
reference_images=[raw_ref, mask_ref],
43+
config=EditImageConfig(
44+
edit_mode="EDIT_MODE_INPAINT_INSERTION",
45+
),
46+
)
47+
48+
image.generated_images[0].image.save(output_file)
49+
50+
print(f"Created output image using {len(image.generated_images[0].image.image_bytes)} bytes")
51+
# Example response:
52+
# Created output image using 1234567 bytes
53+
54+
# [END googlegenaisdk_imggen_inpainting_insert_with_txt_img]
55+
return image.generated_images[0].image
56+
57+
58+
if __name__ == "__main__":
59+
edit_inpainting_insert(output_file="test_resources/fruit_edit.png")
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from google.genai.types import Image
16+
17+
18+
def edit_inpainting_removal(output_file: str) -> Image:
19+
# [START googlegenaisdk_imggen_inpainting_removal_with_txt_img]
20+
from google import genai
21+
from google.genai.types import RawReferenceImage, MaskReferenceImage, MaskReferenceConfig, EditImageConfig
22+
23+
client = genai.Client()
24+
25+
# TODO(developer): Update and un-comment below line
26+
# output_file = "output-image.png"
27+
28+
raw_ref = RawReferenceImage(
29+
reference_image=Image.from_file(location='test_resources/fruit.png'), reference_id=0)
30+
mask_ref = MaskReferenceImage(
31+
reference_id=1,
32+
reference_image=None,
33+
config=MaskReferenceConfig(
34+
mask_mode="MASK_MODE_FOREGROUND",
35+
),
36+
)
37+
38+
image = client.models.edit_image(
39+
model="imagen-3.0-capability-001",
40+
prompt="",
41+
reference_images=[raw_ref, mask_ref],
42+
config=EditImageConfig(
43+
edit_mode="EDIT_MODE_INPAINT_REMOVAL",
44+
),
45+
)
46+
47+
image.generated_images[0].image.save(output_file)
48+
49+
print(f"Created output image using {len(image.generated_images[0].image.image_bytes)} bytes")
50+
# Example response:
51+
# Created output image using 1234567 bytes
52+
53+
# [END googlegenaisdk_imggen_inpainting_removal_with_txt_img]
54+
return image.generated_images[0].image
55+
56+
57+
if __name__ == "__main__":
58+
edit_inpainting_removal(output_file="test_resources/fruit_edit.png")
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from google.genai.types import Image
16+
17+
18+
def edit_mask_free(output_file: str) -> Image:
19+
# [START googlegenaisdk_imggen_mask_free_edit_with_txt_img]
20+
from google import genai
21+
from google.genai.types import RawReferenceImage, EditImageConfig
22+
23+
client = genai.Client()
24+
25+
# TODO(developer): Update and un-comment below line
26+
# output_file = "output-image.png"
27+
28+
raw_ref = RawReferenceImage(
29+
reference_image=Image.from_file(location='test_resources/latte.jpg'), reference_id=0)
30+
31+
image = client.models.edit_image(
32+
model="imagen-3.0-capability-001",
33+
prompt="Swan latte art in the coffee cup and an assortment of red velvet cupcakes in gold wrappers on the white plate",
34+
reference_images=[raw_ref],
35+
config=EditImageConfig(
36+
edit_mode="EDIT_MODE_DEFAULT",
37+
),
38+
)
39+
40+
image.generated_images[0].image.save(output_file)
41+
42+
print(f"Created output image using {len(image.generated_images[0].image.image_bytes)} bytes")
43+
# Example response:
44+
# Created output image using 1234567 bytes
45+
46+
# [END googlegenaisdk_imggen_mask_free_edit_with_txt_img]
47+
return image.generated_images[0].image
48+
49+
50+
if __name__ == "__main__":
51+
edit_mask_free(output_file="test_resources/latte_edit.png")
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from google.genai.types import Image
16+
17+
18+
def edit_outpainting(output_file: str) -> Image:
19+
# [START googlegenaisdk_imggen_outpainting_with_txt_img]
20+
from google import genai
21+
from google.genai.types import RawReferenceImage, MaskReferenceImage, MaskReferenceConfig, EditImageConfig
22+
23+
client = genai.Client()
24+
25+
# TODO(developer): Update and un-comment below line
26+
# output_file = "output-image.png"
27+
28+
raw_ref = RawReferenceImage(
29+
reference_image=Image.from_file(location='test_resources/living_room.png'), reference_id=0)
30+
mask_ref = MaskReferenceImage(
31+
reference_id=1,
32+
reference_image=Image.from_file(location='test_resources/living_room_mask.png'),
33+
config=MaskReferenceConfig(
34+
mask_mode="MASK_MODE_USER_PROVIDED",
35+
mask_dilation=0.03,
36+
),
37+
)
38+
39+
image = client.models.edit_image(
40+
model="imagen-3.0-capability-001",
41+
prompt="A chandelier hanging from the ceiling",
42+
reference_images=[raw_ref, mask_ref],
43+
config=EditImageConfig(
44+
edit_mode="EDIT_MODE_OUTPAINT",
45+
),
46+
)
47+
48+
image.generated_images[0].image.save(output_file)
49+
50+
print(f"Created output image using {len(image.generated_images[0].image.image_bytes)} bytes")
51+
# Example response:
52+
# Created output image using 1234567 bytes
53+
54+
# [END googlegenaisdk_imggen_outpainting_with_txt_img]
55+
return image.generated_images[0].image
56+
57+
58+
if __name__ == "__main__":
59+
edit_outpainting(output_file="test_resources/living_room_edit.png")
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from google.genai.types import Image
16+
17+
18+
def edit_product_background(output_file: str) -> Image:
19+
# [START googlegenaisdk_imggen_product_background_with_txt_img]
20+
from google import genai
21+
from google.genai.types import RawReferenceImage, MaskReferenceImage, MaskReferenceConfig, EditImageConfig
22+
23+
client = genai.Client()
24+
25+
# TODO(developer): Update and un-comment below line
26+
# output_file = "output-image.png"
27+
28+
raw_ref = RawReferenceImage(
29+
reference_image=Image.from_file(location='test_resources/suitcase.png'), reference_id=0)
30+
mask_ref = MaskReferenceImage(
31+
reference_id=1,
32+
reference_image=None,
33+
config=MaskReferenceConfig(
34+
mask_mode="MASK_MODE_BACKGROUND",
35+
),
36+
)
37+
38+
image = client.models.edit_image(
39+
model="imagen-3.0-capability-001",
40+
prompt="A light blue suitcase in front of a window in an airport",
41+
reference_images=[raw_ref, mask_ref],
42+
config=EditImageConfig(
43+
edit_mode="EDIT_MODE_BGSWAP",
44+
),
45+
)
46+
47+
image.generated_images[0].image.save(output_file)
48+
49+
print(f"Created output image using {len(image.generated_images[0].image.image_bytes)} bytes")
50+
# Example response:
51+
# Created output image using 1234567 bytes
52+
53+
# [END googlegenaisdk_imggen_product_background_with_txt_img]
54+
return image.generated_images[0].image
55+
56+
57+
if __name__ == "__main__":
58+
edit_product_background(output_file="test_resources/suitcase_edit.png")

genai/image_generation/test_image_generation.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,14 @@
2525
import pytest
2626

2727
import imggen_canny_ctrl_type_with_txt_img
28+
import imggen_inpainting_insert_with_txt_img
29+
import imggen_inpainting_removal_with_txt_img
30+
import imggen_mask_free_edit_with_txt_img
2831
import imggen_mmflash_edit_img_with_txt_img
2932
import imggen_mmflash_txt_and_img_with_txt
3033
import imggen_mmflash_with_txt
34+
import imggen_outpainting_with_txt_img
35+
import imggen_product_background_with_txt_img
3136
import imggen_raw_reference_with_txt_img
3237
import imggen_scribble_ctrl_type_with_txt_img
3338
import imggen_style_reference_with_txt_img
@@ -42,7 +47,6 @@
4247

4348
GCS_OUTPUT_BUCKET = "python-docs-samples-tests"
4449
RESOURCES = os.path.join(os.path.dirname(__file__), "test_resources")
45-
OUTPUT_FILE = os.path.join(RESOURCES, "dog_newspaper.png")
4650

4751

4852
@pytest.fixture(scope="session")
@@ -58,13 +62,54 @@ def output_gcs_uri() -> str:
5862
blob.delete()
5963

6064

61-
def test_img_generation(output_gcs_uri: str) -> None:
65+
def test_img_generation() -> None:
66+
OUTPUT_FILE = os.path.join(RESOURCES, "dog_newspaper.png")
6267
response = imggen_with_txt.generate_images(
6368
OUTPUT_FILE
6469
)
6570
assert response
6671

6772

73+
def test_img_edit_inpainting_insert() -> None:
74+
OUTPUT_FILE = os.path.join(RESOURCES, "fruit_edit.png")
75+
response = imggen_inpainting_insert_with_txt_img.edit_inpainting_insert(
76+
OUTPUT_FILE
77+
)
78+
assert response
79+
80+
81+
def test_img_edit_inpainting_removal() -> None:
82+
OUTPUT_FILE = os.path.join(RESOURCES, "fruit_edit.png")
83+
response = imggen_inpainting_removal_with_txt_img.edit_inpainting_removal(
84+
OUTPUT_FILE
85+
)
86+
assert response
87+
88+
89+
def test_img_edit_product_background() -> None:
90+
OUTPUT_FILE = os.path.join(RESOURCES, "suitcase_edit.png")
91+
response = imggen_product_background_with_txt_img.edit_product_background(
92+
OUTPUT_FILE
93+
)
94+
assert response
95+
96+
97+
def test_img_edit_outpainting() -> None:
98+
OUTPUT_FILE = os.path.join(RESOURCES, "living_room_edit.png")
99+
response = imggen_outpainting_with_txt_img.edit_outpainting(
100+
OUTPUT_FILE
101+
)
102+
assert response
103+
104+
105+
def test_img_edit_mask_free() -> None:
106+
OUTPUT_FILE = os.path.join(RESOURCES, "latte_edit.png")
107+
response = imggen_mask_free_edit_with_txt_img.edit_mask_free(
108+
OUTPUT_FILE
109+
)
110+
assert response
111+
112+
68113
def test_img_customization_subject(output_gcs_uri: str) -> None:
69114
response = imggen_subj_refer_ctrl_refer_with_txt_imgs.subject_customization(
70115
output_gcs_uri=output_gcs_uri
1.22 MB
Loading
Loading
72.5 KB
Loading
Loading

0 commit comments

Comments
 (0)