diff --git a/genai/snippets/src/main/java/genai/boundingbox/BoundingBoxWithTxtImg.java b/genai/snippets/src/main/java/genai/boundingbox/BoundingBoxWithTxtImg.java index 8988c7c8d01..e7b13c11507 100644 --- a/genai/snippets/src/main/java/genai/boundingbox/BoundingBoxWithTxtImg.java +++ b/genai/snippets/src/main/java/genai/boundingbox/BoundingBoxWithTxtImg.java @@ -90,8 +90,12 @@ public static void plotBoundingBoxes(String imageUrl, List bounding Color.ORANGE); for (int i = 0; i < boundingBoxes.size(); i++) { - BoundingBox boundingBox = boundingBoxes.get((i)); + BoundingBox boundingBox = boundingBoxes.get(i); List box2d = boundingBox.getBox2d(); + // Prevents IndexOutOfBoundsException + if (box2d == null || box2d.size() < 4) { + continue; + } // Scale normalized coordinates (0-1000) to image dimensions. int topY = (int) (box2d.get(0) / 1000.0 * height); diff --git a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenCannyCtrlTypeWithTextAndImage.java b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenCannyCtrlTypeWithTextAndImage.java index b42619eee68..b213721e566 100644 --- a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenCannyCtrlTypeWithTextAndImage.java +++ b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenCannyCtrlTypeWithTextAndImage.java @@ -18,21 +18,24 @@ // [START googlegenaisdk_imggen_canny_ctrl_type_with_txt_img] +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; import com.google.genai.Client; -import com.google.genai.types.ControlReferenceConfig; -import com.google.genai.types.ControlReferenceImage; -import com.google.genai.types.EditImageConfig; -import com.google.genai.types.EditImageResponse; -import com.google.genai.types.GeneratedImage; -import com.google.genai.types.Image; -import java.util.List; +import com.google.genai.types.Blob; +import com.google.genai.types.Candidate; +import com.google.genai.types.Content; +import com.google.genai.types.GenerateContentConfig; +import com.google.genai.types.GenerateContentResponse; +import com.google.genai.types.Part; import java.util.Optional; public class ImageGenCannyCtrlTypeWithTextAndImage { public static void main(String[] args) { // TODO(developer): Replace these variables before running the sample. - String modelId = "imagen-3.0-capability-001"; + String modelId = "gemini-2.5-flash-image"; String outputGcsUri = "gs://your-bucket/your-prefix"; cannyEdgeCustomization(modelId, outputGcsUri); } @@ -41,44 +44,48 @@ public static void main(String[] args) { public static Optional cannyEdgeCustomization(String modelId, String outputGcsUri) { // Client Initialization. Once created, it can be reused for multiple requests. try (Client client = Client.builder().location("global").vertexAI(true).build()) { - // Create a reference image out of an existing canny edge image signal - // using https://storage.googleapis.com/cloud-samples-data/generative-ai/image/car_canny.png - ControlReferenceImage controlReferenceImage = - ControlReferenceImage.builder() - .referenceId(1) - .referenceImage( - Image.builder() - .gcsUri("gs://cloud-samples-data/generative-ai/image/car_canny.png") - .build()) - .config(ControlReferenceConfig.builder().controlType("CONTROL_TYPE_CANNY").build()) - .build(); - // The `[1]` in the prompt refers to the `referenceId` assigned to - // the control reference image. - EditImageResponse imageResponse = - client.models.editImage( + GenerateContentConfig config = + GenerateContentConfig.builder().responseModalities("TEXT", "IMAGE").build(); + + GenerateContentResponse response = + client.models.generateContent( modelId, - "a watercolor painting of a red car[1] driving on a road", - List.of(controlReferenceImage), - EditImageConfig.builder() - .editMode("EDIT_MODE_CONTROLLED_EDITING") - .numberOfImages(1) - .safetyFilterLevel("BLOCK_MEDIUM_AND_ABOVE") - .personGeneration("ALLOW_ADULT") - .outputGcsUri(outputGcsUri) - .build()); + Content.fromParts( + Part.fromUri( + "gs://cloud-samples-data/generative-ai/image/car_canny.png", "image/png"), + Part.fromText("a watercolor painting of a red car driving on a road")), + config); - Image generatedImage = - imageResponse - .generatedImages() - .flatMap(generatedImages -> generatedImages.stream().findFirst()) - .flatMap(GeneratedImage::image) + byte[] imageBytes = + response + .candidates() + .flatMap(candidates -> candidates.stream().findFirst()) + .flatMap(Candidate::content) + .flatMap(Content::parts) + .flatMap( + parts -> + parts.stream() + .filter(part -> part.inlineData().flatMap(Blob::data).isPresent()) + .findFirst()) + .flatMap(part -> part.inlineData().flatMap(Blob::data)) .orElseThrow(() -> new IllegalStateException("No image was generated by the model.")); - generatedImage.gcsUri().ifPresent(System.out::println); - // Example response: - // gs://your-bucket/your-prefix - return generatedImage.gcsUri(); + Storage storage = StorageOptions.getDefaultInstance().getService(); + String gcsPath = outputGcsUri.replace("gs://", ""); + int slashIdx = gcsPath.indexOf('/'); + String bucket = slashIdx > 0 ? gcsPath.substring(0, slashIdx) : gcsPath; + String objectName = + slashIdx > 0 + ? gcsPath.substring(slashIdx + 1) + "/canny_customization.png" + : "canny_customization.png"; + BlobId blobId = BlobId.of(bucket, objectName); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/png").build(); + storage.create(blobInfo, imageBytes); + + String fullGcsUri = String.format("gs://%s/%s", bucket, objectName); + System.out.println("Generated image URI: " + fullGcsUri); + return Optional.of(fullGcsUri); } } } diff --git a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenRawReferenceWithTextAndImage.java b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenRawReferenceWithTextAndImage.java index 51ab77002a7..b20247a1d2a 100644 --- a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenRawReferenceWithTextAndImage.java +++ b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenRawReferenceWithTextAndImage.java @@ -18,20 +18,24 @@ // [START googlegenaisdk_imggen_raw_reference_with_txt_img] +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; import com.google.genai.Client; -import com.google.genai.types.EditImageConfig; -import com.google.genai.types.EditImageResponse; -import com.google.genai.types.GeneratedImage; -import com.google.genai.types.Image; -import com.google.genai.types.RawReferenceImage; -import java.util.List; +import com.google.genai.types.Blob; +import com.google.genai.types.Candidate; +import com.google.genai.types.Content; +import com.google.genai.types.GenerateContentConfig; +import com.google.genai.types.GenerateContentResponse; +import com.google.genai.types.Part; import java.util.Optional; public class ImageGenRawReferenceWithTextAndImage { public static void main(String[] args) { // TODO(developer): Replace these variables before running the sample. - String modelId = "imagen-3.0-capability-001"; + String modelId = "gemini-2.5-flash-image"; String outputGcsUri = "gs://your-bucket/your-prefix"; styleTransferCustomization(modelId, outputGcsUri); } @@ -41,43 +45,50 @@ public static void main(String[] args) { public static Optional styleTransferCustomization(String modelId, String outputGcsUri) { // Client Initialization. Once created, it can be reused for multiple requests. try (Client client = Client.builder().location("global").vertexAI(true).build()) { - // Create a raw reference image of teacup stored in Google Cloud Storage - // using https://storage.googleapis.com/cloud-samples-data/generative-ai/image/teacup-1.png - RawReferenceImage rawReferenceImage = - RawReferenceImage.builder() - .referenceId(1) - .referenceImage( - Image.builder() - .gcsUri("gs://cloud-samples-data/generative-ai/image/teacup-1.png") - .build()) - .build(); - // The `[1]` in the prompt refers to the `referenceId` assigned to the raw reference image. - EditImageResponse imageResponse = - client.models.editImage( + GenerateContentConfig config = + GenerateContentConfig.builder().responseModalities("TEXT", "IMAGE").build(); + + GenerateContentResponse response = + client.models.generateContent( modelId, - "transform the subject in the image so that " - + "the teacup[1] is made entirely out of chocolate", - List.of(rawReferenceImage), - EditImageConfig.builder() - .editMode("EDIT_MODE_DEFAULT") - .numberOfImages(1) - .safetyFilterLevel("BLOCK_MEDIUM_AND_ABOVE") - .personGeneration("ALLOW_ADULT") - .outputGcsUri(outputGcsUri) - .build()); + Content.fromParts( + Part.fromUri( + "gs://cloud-samples-data/generative-ai/image/teacup-1.png", "image/png"), + Part.fromText( + "transform the subject in the image so that " + + "the teacup is made entirely out of chocolate")), + config); - Image generatedImage = - imageResponse - .generatedImages() - .flatMap(generatedImages -> generatedImages.stream().findFirst()) - .flatMap(GeneratedImage::image) + byte[] imageBytes = + response + .candidates() + .flatMap(candidates -> candidates.stream().findFirst()) + .flatMap(Candidate::content) + .flatMap(Content::parts) + .flatMap( + parts -> + parts.stream() + .filter(part -> part.inlineData().flatMap(Blob::data).isPresent()) + .findFirst()) + .flatMap(part -> part.inlineData().flatMap(Blob::data)) .orElseThrow(() -> new IllegalStateException("No image was generated by the model.")); - generatedImage.gcsUri().ifPresent(System.out::println); - // Example response: - // gs://your-bucket/your-prefix - return generatedImage.gcsUri(); + Storage storage = StorageOptions.getDefaultInstance().getService(); + String gcsPath = outputGcsUri.replace("gs://", ""); + int slashIdx = gcsPath.indexOf('/'); + String bucket = slashIdx > 0 ? gcsPath.substring(0, slashIdx) : gcsPath; + String objectName = + slashIdx > 0 + ? gcsPath.substring(slashIdx + 1) + "/raw_reference.png" + : "raw_reference.png"; + BlobId blobId = BlobId.of(bucket, objectName); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/png").build(); + storage.create(blobInfo, imageBytes); + + String fullGcsUri = String.format("gs://%s/%s", bucket, objectName); + System.out.println("Generated image URI: " + fullGcsUri); + return Optional.of(fullGcsUri); } } } diff --git a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenScribbleCtrlTypeWithTextAndImage.java b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenScribbleCtrlTypeWithTextAndImage.java index 1cfb351e7a8..559b4be07e1 100644 --- a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenScribbleCtrlTypeWithTextAndImage.java +++ b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenScribbleCtrlTypeWithTextAndImage.java @@ -18,21 +18,24 @@ // [START googlegenaisdk_imggen_scribble_ctrl_type_with_txt_img] +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; import com.google.genai.Client; -import com.google.genai.types.ControlReferenceConfig; -import com.google.genai.types.ControlReferenceImage; -import com.google.genai.types.EditImageConfig; -import com.google.genai.types.EditImageResponse; -import com.google.genai.types.GeneratedImage; -import com.google.genai.types.Image; -import java.util.List; +import com.google.genai.types.Blob; +import com.google.genai.types.Candidate; +import com.google.genai.types.Content; +import com.google.genai.types.GenerateContentConfig; +import com.google.genai.types.GenerateContentResponse; +import com.google.genai.types.Part; import java.util.Optional; public class ImageGenScribbleCtrlTypeWithTextAndImage { public static void main(String[] args) { // TODO(developer): Replace these variables before running the sample. - String modelId = "imagen-3.0-capability-001"; + String modelId = "gemini-2.5-flash-image"; String outputGcsUri = "gs://your-bucket/your-prefix"; scribbleCustomization(modelId, outputGcsUri); } @@ -41,46 +44,48 @@ public static void main(String[] args) { public static Optional scribbleCustomization(String modelId, String outputGcsUri) { // Client Initialization. Once created, it can be reused for multiple requests. try (Client client = Client.builder().location("global").vertexAI(true).build()) { - // Create a reference image out of an existing scribble image signal - // using - // https://storage.googleapis.com/cloud-samples-data/generative-ai/image/car_scribble.png - ControlReferenceImage controlReferenceImage = - ControlReferenceImage.builder() - .referenceId(1) - .referenceImage( - Image.builder() - .gcsUri("gs://cloud-samples-data/generative-ai/image/car_scribble.png") - .build()) - .config(ControlReferenceConfig.builder().controlType("CONTROL_TYPE_SCRIBBLE").build()) - .build(); - // The `[1]` in the prompt refers to the `referenceId` assigned to the - // control reference image. - EditImageResponse imageResponse = - client.models.editImage( + GenerateContentConfig config = + GenerateContentConfig.builder().responseModalities("TEXT", "IMAGE").build(); + + GenerateContentResponse response = + client.models.generateContent( modelId, - "an oil painting showing the side of a red car[1]", - List.of(controlReferenceImage), - EditImageConfig.builder() - .editMode("EDIT_MODE_CONTROLLED_EDITING") - .numberOfImages(1) - .safetyFilterLevel("BLOCK_MEDIUM_AND_ABOVE") - .personGeneration("ALLOW_ADULT") - .outputGcsUri(outputGcsUri) - .build()); + Content.fromParts( + Part.fromUri( + "gs://cloud-samples-data/generative-ai/image/car_scribble.png", "image/png"), + Part.fromText("an oil painting showing the side of a red car")), + config); - Image generatedImage = - imageResponse - .generatedImages() - .flatMap(generatedImages -> generatedImages.stream().findFirst()) - .flatMap(GeneratedImage::image) + byte[] imageBytes = + response + .candidates() + .flatMap(candidates -> candidates.stream().findFirst()) + .flatMap(Candidate::content) + .flatMap(Content::parts) + .flatMap( + parts -> + parts.stream() + .filter(part -> part.inlineData().flatMap(Blob::data).isPresent()) + .findFirst()) + .flatMap(part -> part.inlineData().flatMap(Blob::data)) .orElseThrow(() -> new IllegalStateException("No image was generated by the model.")); - generatedImage.gcsUri().ifPresent(System.out::println); - // Example response: - // gs://your-bucket/your-prefix + Storage storage = StorageOptions.getDefaultInstance().getService(); + String gcsPath = outputGcsUri.replace("gs://", ""); + int slashIdx = gcsPath.indexOf('/'); + String bucket = slashIdx > 0 ? gcsPath.substring(0, slashIdx) : gcsPath; + String objectName = + slashIdx > 0 + ? gcsPath.substring(slashIdx + 1) + "/scribble_customization.png" + : "scribble_customization.png"; + BlobId blobId = BlobId.of(bucket, objectName); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/png").build(); + storage.create(blobInfo, imageBytes); - return generatedImage.gcsUri(); + String fullGcsUri = String.format("gs://%s/%s", bucket, objectName); + System.out.println("Generated image URI: " + fullGcsUri); + return Optional.of(fullGcsUri); } } } diff --git a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenStyleReferenceWithTextAndImage.java b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenStyleReferenceWithTextAndImage.java index ee49522f6ec..4e4e3bcff93 100644 --- a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenStyleReferenceWithTextAndImage.java +++ b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenStyleReferenceWithTextAndImage.java @@ -18,21 +18,24 @@ // [START googlegenaisdk_imggen_style_reference_with_txt_img] +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; import com.google.genai.Client; -import com.google.genai.types.EditImageConfig; -import com.google.genai.types.EditImageResponse; -import com.google.genai.types.GeneratedImage; -import com.google.genai.types.Image; -import com.google.genai.types.StyleReferenceConfig; -import com.google.genai.types.StyleReferenceImage; -import java.util.List; +import com.google.genai.types.Blob; +import com.google.genai.types.Candidate; +import com.google.genai.types.Content; +import com.google.genai.types.GenerateContentConfig; +import com.google.genai.types.GenerateContentResponse; +import com.google.genai.types.Part; import java.util.Optional; public class ImageGenStyleReferenceWithTextAndImage { public static void main(String[] args) { // TODO(developer): Replace these variables before running the sample. - String modelId = "imagen-3.0-capability-001"; + String modelId = "gemini-2.5-flash-image"; String outputGcsUri = "gs://your-bucket/your-prefix"; styleCustomization(modelId, outputGcsUri); } @@ -41,44 +44,48 @@ public static void main(String[] args) { public static Optional styleCustomization(String modelId, String outputGcsUri) { // Client Initialization. Once created, it can be reused for multiple requests. try (Client client = Client.builder().location("global").vertexAI(true).build()) { - // Create a style reference image of a neon sign stored in Google Cloud Storage - // using https://storage.googleapis.com/cloud-samples-data/generative-ai/image/neon.png - StyleReferenceImage styleReferenceImage = - StyleReferenceImage.builder() - .referenceId(1) - .referenceImage( - Image.builder() - .gcsUri("gs://cloud-samples-data/generative-ai/image/neon.png") - .build()) - .config(StyleReferenceConfig.builder().styleDescription("neon sign").build()) - .build(); - // The `[1]` in the prompt refers to the `referenceId` assigned to the style reference image. - EditImageResponse imageResponse = - client.models.editImage( + GenerateContentConfig config = + GenerateContentConfig.builder().responseModalities("TEXT", "IMAGE").build(); + + GenerateContentResponse response = + client.models.generateContent( modelId, - "generate an image of a neon sign [1] with the words: have a great day", - List.of(styleReferenceImage), - EditImageConfig.builder() - .editMode("EDIT_MODE_DEFAULT") - .numberOfImages(1) - .safetyFilterLevel("BLOCK_MEDIUM_AND_ABOVE") - .personGeneration("ALLOW_ADULT") - .outputGcsUri(outputGcsUri) - .build()); + Content.fromParts( + Part.fromUri("gs://cloud-samples-data/generative-ai/image/neon.png", "image/png"), + Part.fromText( + "generate an image of a neon sign with the words: have a great day")), + config); - Image generatedImage = - imageResponse - .generatedImages() - .flatMap(generatedImages -> generatedImages.stream().findFirst()) - .flatMap(GeneratedImage::image) + byte[] imageBytes = + response + .candidates() + .flatMap(candidates -> candidates.stream().findFirst()) + .flatMap(Candidate::content) + .flatMap(Content::parts) + .flatMap( + parts -> + parts.stream() + .filter(part -> part.inlineData().flatMap(Blob::data).isPresent()) + .findFirst()) + .flatMap(part -> part.inlineData().flatMap(Blob::data)) .orElseThrow(() -> new IllegalStateException("No image was generated by the model.")); - generatedImage.gcsUri().ifPresent(System.out::println); - // Example response: - // gs://your-bucket/your-prefix + Storage storage = StorageOptions.getDefaultInstance().getService(); + String gcsPath = outputGcsUri.replace("gs://", ""); + int slashIdx = gcsPath.indexOf('/'); + String bucket = slashIdx > 0 ? gcsPath.substring(0, slashIdx) : gcsPath; + String objectName = + slashIdx > 0 + ? gcsPath.substring(slashIdx + 1) + "/style_customization.png" + : "style_customization.png"; + BlobId blobId = BlobId.of(bucket, objectName); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/png").build(); + storage.create(blobInfo, imageBytes); - return generatedImage.gcsUri(); + String fullGcsUri = String.format("gs://%s/%s", bucket, objectName); + System.out.println("Generated image URI: " + fullGcsUri); + return Optional.of(fullGcsUri); } } } diff --git a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenSubjectReferenceWithTextAndImage.java b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenSubjectReferenceWithTextAndImage.java index 58b10eb5a94..b2170dfbe2b 100644 --- a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenSubjectReferenceWithTextAndImage.java +++ b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenSubjectReferenceWithTextAndImage.java @@ -18,89 +18,79 @@ // [START googlegenaisdk_imggen_subj_refer_ctrl_refer_with_txt_imgs] +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; import com.google.genai.Client; -import com.google.genai.types.ControlReferenceConfig; -import com.google.genai.types.ControlReferenceImage; -import com.google.genai.types.EditImageConfig; -import com.google.genai.types.EditImageResponse; -import com.google.genai.types.GeneratedImage; -import com.google.genai.types.Image; -import com.google.genai.types.SubjectReferenceConfig; -import com.google.genai.types.SubjectReferenceImage; -import java.util.List; +import com.google.genai.types.Blob; +import com.google.genai.types.Candidate; +import com.google.genai.types.Content; +import com.google.genai.types.GenerateContentConfig; +import com.google.genai.types.GenerateContentResponse; +import com.google.genai.types.Part; import java.util.Optional; public class ImageGenSubjectReferenceWithTextAndImage { public static void main(String[] args) { // TODO(developer): Replace these variables before running the sample. - String modelId = "imagen-3.0-capability-001"; + String modelId = "gemini-2.5-flash-image"; String outputGcsUri = "gs://your-bucket/your-prefix"; subjectCustomization(modelId, outputGcsUri); } // Generates an image using subject customization by adapting a subject reference image - // with a control reference image and a text prompt. + // with a text prompt. public static Optional subjectCustomization(String modelId, String outputGcsUri) { // Client Initialization. Once created, it can be reused for multiple requests. try (Client client = Client.builder().location("global").vertexAI(true).build()) { - // Create subject and control reference images of a photograph stored in Google Cloud Storage - // using https://storage.googleapis.com/cloud-samples-data/generative-ai/image/person.png - SubjectReferenceImage subjectReferenceImage = - SubjectReferenceImage.builder() - .referenceId(1) - .referenceImage( - Image.builder() - .gcsUri("gs://cloud-samples-data/generative-ai/image/person.png") - .build()) - .config( - SubjectReferenceConfig.builder() - .subjectDescription("a headshot of a woman") - .subjectType("SUBJECT_TYPE_PERSON") - .build()) - .build(); - ControlReferenceImage controlReferenceImage = - ControlReferenceImage.builder() - .referenceId(2) - .referenceImage( - Image.builder() - .gcsUri("gs://cloud-samples-data/generative-ai/image/person.png") - .build()) - .config( - ControlReferenceConfig.builder().controlType("CONTROL_TYPE_FACE_MESH").build()) - .build(); + GenerateContentConfig config = + GenerateContentConfig.builder().responseModalities("TEXT", "IMAGE").build(); - // The `[1]` and `[2]` in the prompt refer to the `referenceId` assigned to - // the subject reference and control reference images. - EditImageResponse imageResponse = - client.models.editImage( + GenerateContentResponse response = + client.models.generateContent( modelId, - "a portrait of a woman[1] in the pose of the control image[2]in a watercolor style by" - + " a professional artist, light and low-contrast stokes, bright pastel colors," - + " a warm atmosphere, clean background, grainy paper, bold visible brushstrokes," - + " patchy details", - List.of(subjectReferenceImage, controlReferenceImage), - EditImageConfig.builder() - .editMode("EDIT_MODE_DEFAULT") - .numberOfImages(1) - .safetyFilterLevel("BLOCK_MEDIUM_AND_ABOVE") - .personGeneration("ALLOW_ADULT") - .outputGcsUri(outputGcsUri) - .build()); + Content.fromParts( + Part.fromUri( + "gs://cloud-samples-data/generative-ai/image/person.png", "image/png"), + Part.fromText( + "a portrait of the woman in a watercolor style by a professional artist," + + " light and low-contrast strokes, bright pastel colors, a warm" + + " atmosphere, clean background, grainy paper, bold visible" + + " brushstrokes, patchy details")), + config); - Image generatedImage = - imageResponse - .generatedImages() - .flatMap(generatedImages -> generatedImages.stream().findFirst()) - .flatMap(GeneratedImage::image) + byte[] imageBytes = + response + .candidates() + .flatMap(candidates -> candidates.stream().findFirst()) + .flatMap(Candidate::content) + .flatMap(Content::parts) + .flatMap( + parts -> + parts.stream() + .filter(part -> part.inlineData().flatMap(Blob::data).isPresent()) + .findFirst()) + .flatMap(part -> part.inlineData().flatMap(Blob::data)) .orElseThrow(() -> new IllegalStateException("No image was generated by the model.")); - generatedImage.gcsUri().ifPresent(System.out::println); - // Example response: - // gs://your-bucket/your-prefix + Storage storage = StorageOptions.getDefaultInstance().getService(); + String gcsPath = outputGcsUri.replace("gs://", ""); + int slashIdx = gcsPath.indexOf('/'); + String bucket = slashIdx > 0 ? gcsPath.substring(0, slashIdx) : gcsPath; + String objectName = + slashIdx > 0 + ? gcsPath.substring(slashIdx + 1) + "/subject_customization.png" + : "subject_customization.png"; + BlobId blobId = BlobId.of(bucket, objectName); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/png").build(); + storage.create(blobInfo, imageBytes); - return generatedImage.gcsUri(); + String fullGcsUri = String.format("gs://%s/%s", bucket, objectName); + System.out.println("Generated image URI: " + fullGcsUri); + return Optional.of(fullGcsUri); } } } diff --git a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenWithText.java b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenWithText.java index 56d565541e2..507eed252e0 100644 --- a/genai/snippets/src/main/java/genai/imagegeneration/ImageGenWithText.java +++ b/genai/snippets/src/main/java/genai/imagegeneration/ImageGenWithText.java @@ -66,10 +66,9 @@ public static Image generateImage(String modelId, String outputFile) throws IOEx .flatMap(part -> part.inlineData().flatMap(Blob::data)) .orElseThrow(() -> new IllegalStateException("No image was generated by the model.")); - BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes)); - ImageIO.write(image, "png", new File(outputFile)); + java.nio.file.Files.write(java.nio.file.Paths.get(outputFile), imageBytes); - System.out.printf("Created output image using %d bytes\n", imageBytes.length); + System.out.printf("Created output image using %s bytes\n", imageBytes.length); return Image.builder().imageBytes(imageBytes).build(); } diff --git a/genai/snippets/src/test/java/genai/imagegeneration/ImageGenerationMmFlashIT.java b/genai/snippets/src/test/java/genai/imagegeneration/ImageGenerationMmFlashIT.java index e9c4d011d00..85b260bcce6 100644 --- a/genai/snippets/src/test/java/genai/imagegeneration/ImageGenerationMmFlashIT.java +++ b/genai/snippets/src/test/java/genai/imagegeneration/ImageGenerationMmFlashIT.java @@ -79,6 +79,9 @@ public void testImageGenMmFlashLocaleAwareWithText() throws IOException { @Test public void testImageGenMmFlashMultipleImagesWithText() throws IOException { List images = ImageGenMmFlashMultipleImagesWithText.generateContent(GEMINI_FLASH_IMAGE); + if (images.isEmpty()) { + images = ImageGenMmFlashMultipleImagesWithText.generateContent(GEMINI_FLASH_IMAGE); + } assertThat(images).isNotEmpty(); }