diff --git a/.github/workflows/packaging.yaml b/.github/workflows/packaging.yaml index d69e05d64..40a05e7e7 100644 --- a/.github/workflows/packaging.yaml +++ b/.github/workflows/packaging.yaml @@ -57,7 +57,7 @@ jobs: pkg_version: ${{ steps.build.outputs.pkg_version }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install R uses: r-lib/actions/setup-r@v2 diff --git a/.github/workflows/pr-commands.yaml b/.github/workflows/pr-commands.yaml index 8bbbd9c27..7f8223db1 100644 --- a/.github/workflows/pr-commands.yaml +++ b/.github/workflows/pr-commands.yaml @@ -14,7 +14,7 @@ jobs: env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/pr-fetch@v2 with: @@ -52,7 +52,7 @@ jobs: env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/pr-fetch@v2 with: @@ -89,14 +89,14 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} VERSION: ${{ github.event.comment.body }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/pr-fetch@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: r-lib/actions/setup-r@v2 - + - name: Version id: version run: | @@ -122,7 +122,7 @@ jobs: writeLines(lines, desc) } } - + paws_update_version("cran") shell: Rscript {0} diff --git a/.github/workflows/regen.yml b/.github/workflows/regen.yml index 5a8a49ed8..2f590c560 100644 --- a/.github/workflows/regen.yml +++ b/.github/workflows/regen.yml @@ -18,7 +18,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install R uses: r-lib/actions/setup-r@v2 diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 50021bb0f..fe0a2568c 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -29,7 +29,7 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install R uses: r-lib/actions/setup-r@v2 @@ -67,7 +67,7 @@ jobs: shell: Rscript {0} - name: Cache R packages - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ${{ env.R_LIBS_USER }} key: ${{ runner.os }}-${{ matrix.config.R }}-1-${{ hashFiles('.github/depends.Rds') }} diff --git a/examples/amazon_nova_example/amazon-coffee-maker-1.png b/examples/amazon_nova_example/amazon-coffee-maker-1.png new file mode 100644 index 000000000..b4b56c3a1 Binary files /dev/null and b/examples/amazon_nova_example/amazon-coffee-maker-1.png differ diff --git a/examples/amazon_nova_example/image_1.png b/examples/amazon_nova_example/image_1.png new file mode 100644 index 000000000..05587f24a Binary files /dev/null and b/examples/amazon_nova_example/image_1.png differ diff --git a/examples/aws_nova_background_generation_guide.md b/examples/aws_nova_background_generation_guide.md new file mode 100644 index 000000000..616b120a6 --- /dev/null +++ b/examples/aws_nova_background_generation_guide.md @@ -0,0 +1,137 @@ +## Background replacement with Amazon Bedrock in R: A Step-by-Step Guide + +Developed from [05_background_replacement_using_mask_prompt](https://github.com/aws-samples/amazon-nova-samples/blob/main/multimodal-generation/image-generation/notebook/05_background_replacement_using_mask_prompt.ipynb) + +### 1. Load Necessary Libraries + +First, we need to load the required libraries for AWS services, JSON handling, base64 encoding/decoding, and image processing. + +```r +library(paws) +library(yyjsonr) +library(base64enc) +library(magick) +``` + +### 2. Define the Image Generation Function + +Next, we define a helper function `generate_images` that will handle the image generation process using Amazon Bedrock. + +```r +# Function to generate images using Amazon Nova +generate_images <- function( + inference_params, + output_directory, + model_id = "amazon.nova-canvas-v1:0", + client = NULL) { + # Create client if not provided + client <- client %||% bedrockruntime(region = "us-east-1") + + # Invoke the model with the provided parameters + resp <- client$invoke_model( + body = write_json_str(inference_params, auto_unbox = TRUE), + modelId = model_id, + accept = "application/json", + contentType = "application/json" + ) + + # Create the output directory if it doesn't exist + dir.create(output_directory, recursive = TRUE, showWarnings = FALSE) + + # Read the response body and decode the images + resp_body <- read_json_raw(resp$body) + img_raw <- lapply(resp_body$images, base64decode) + img <- lapply(img_raw, image_read) + + # Save the request and response to JSON files + write_json_file( + inference_params, + file.path(output_directory, "request.json"), + auto_unbox = TRUE, pretty = TRUE + ) + write_json_file( + resp_body, + file.path(output_directory, "response_body.json"), + auto_unbox = TRUE, pretty = TRUE + ) + + # Save the generated images to the output directory + for (i in seq_along(img)) { + image_write( + img[[i]], file.path(output_directory, sprintf("image_%s.png", i)) + ) + } +} +``` + +### 3. Set Up Directories and Source Image + +We define the directories and specify the source image that we want to use for the image generation task. + +```r +# Define directories and source image +DIR <- "amazon_nova_example" +SOURCE_IMAGE <- file.path(DIR, "images/amazon-coffee-maker-1.png") +``` + +### 4. Encode the Source Image + +The source image is encoded to base64 format, which is required for the inference parameters. + +```r +# Encode the source image to base64 +SOURCE_IMAGE_BASE64 = base64encode(SOURCE_IMAGE) +``` + +### 5. Define Inference Parameters + +We set up the parameters for the image generation task, including the task type, description, mask prompt, and configuration. + +```r +# Define inference parameters for the image generation task +INFERENCE_PARAMS <- list( + taskType= "OUTPAINTING", + outPaintingParams= list( + image= SOURCE_IMAGE_BASE64, + text= "a coffee maker in a sparse stylish kitchen, a single plate of pastries next to the coffee maker, a single cup of coffee. highly detailed, highest quality, product imagery", # Description of the background to generate + maskPrompt= "coffee maker", # The element(s) to keep + outPaintingMode= "PRECISE" # "DEFAULT" softens the mask. "PRECISE" keeps it sharp. + ), + imageGenerationConfig = list( + numberOfImages= 1, # Number of variations to generate. 1 to 5. + quality= "standard", # Allowed values are "standard" and "premium" + cfgScale= 7.0, # How closely the prompt will be followed + seed= 123L # Set Seed + ) +) +``` + +### 6. Generate a Unique ID for the Output Directory + +We create a unique ID for the output directory to ensure that each run of the script saves its results in a separate folder. + +```r +# Generate a unique ID for the output directory +GENERATION_ID <- strftime(Sys.time(), format = "%Y-%m-%d_%H-%M-%S") +OUTPUT_DIR <- file.path(DIR, "output", GENERATION_ID) +``` + +### 7. Call the Function to Generate Images + +Finally, we call the `generate_images` function with the defined parameters and output directory to generate the images. + +```r +# Call the function to generate images +generate_images(INFERENCE_PARAMS, OUTPUT_DIR) +``` + +