Using FMs Stable Diffusion in AWS Bedrock to Generate Images

Using FMs Stable Diffusion in AWS Bedrock to Generate Images

avatar

Minh Huynh

2025.03.26

No doubt that Generative AI is now being used by nearly everyone in the technology industry, it helps a lot of people daily with their work, life and almost everything. Generative AI is type of AI that is used to generate contents such as texts, images and videos based on the data that the models trained on. In this article we will building an API that invoke AWS Bedrock to generate images using SDXL 1.0 model.

Lab Introduction

  • AWS experience: Intermediate
  • Time to complete: 35 minutes
  • AWS Region: US East (N. Virginia) us-east-1
  • Cost to complete: (Optional) Free Tier eligible
  • Services used: API Gateway, Lambda, Bedrock, S3

Architecture Diagram

Amazon Bedrock is a managed service that offers these foundation model to be used or to you can use some AWS bedrock to train these models with your own data and use it with other AWS services to build your application.

In this article we will building an API that invoke AWS Bedrock to generate images using SDXL 1.0 model.

We will use the below services

  • Lambda function which contain the logic and integrate with AWS Bedrock
  • API Gateway which exposes the Lambda function
  • AWS Bedrock with Stable Diffusion Model
  • S3 bucket to store the images

1. Create S3 bucket and request access FMs

  1. Create S3 bucket with default configuration Go to S3 Console --> Create Bucket --> Leave the default settings. This bucket will be used to store the generated images and will be used to generate a pre-signed URLs to have temporary access to these images.
  2. Request access to Amazon Bedrock Stable Diffusion model Go to Bedrock Console --> Base Models under Foundation Models --> Request model access. You will have access after few minutes, after than you are ready to go.
  3. Get the model ID since it will be used later in Lambda python code Go to Bedrock Console --> Click Model catalog --> Check Image in Modality --> Click SDXL 1.0.
  4. Select View API Request you will get a sample request to interact with this model as below. Note down the model id: stability.stable-diffusion-xl-v1

2. Create Lambda function

  1. Create Lambda function with name: stable-diffusion-bedrock-generative-image-function and Runtime: Python 3.13. Choose button Create function.
  2. Update role Lambda interaction with Bedrock and S3. Tab Configuration -> Choose Permission -> Role name -> Add permission with S3FullAccess,BedrockFullAccess.
  3. Increase AWS Lambda Timeout using generative image 3D: Under Configuration → General Configuration → Edit, increase the Timeout setting. Recommended**:** Set to 1min30 seconds or higher.

3. Explain Code

  • First you need to import the below packages.
import json # for converting the payload into JSON
import boto3 # to interact with AWS services
import base64 # it will be used to encode the images 
import datetime # will be used to interact with date and time functions
  • To interact with AWS services you will need to define client for the services below we are going to interact with bedrock and S3 so we will have two clients.
bedrock_client = boto3.client('bedrock-runtime')
s3_client = boto3.client('s3')
  • Then you will get the input from prompt text from the API gateway.
  input_text = event['prompt']
  print(input_text) # for troubleshooting
  • Now you will need to configure the parameter for invoking the Stable Diffusion model, You can find the full parameters here. I used the below:
payload = {
        "text_prompts": [ #(Required)An array of text prompts to use for generation. 
            {
                "text": input_text # The prompt that you want to pass to the model.
            }
        ],
        "height": 1024, # (Optional) Height of the image to generate
        "width": 1024, # (Optional) Width of the image to generate
        "cfg_scale": 7, # (Optional) Determines how much the final image portrays the prompt.
        "steps": 50, # (Optional) Generation step determines how many times the image is sampled
        "style_preset": "photographic" # A style preset that guides the image model towards a particular style
    }

# Now we are invoking the model 
    response = bedrock_client.invoke_model( 
        body=json.dumps(payload),
        contentType='application/json', # The MIME type of the input data in the request.
        accept='application/json', #The desired MIME type of the inference body in the response.
        modelId='stability.stable-diffusion-xl-v1' #model ID
    )
  • We will now work to extract the image from the response and we will use base64 to decode it.
    response_byte=json.loads(response['body'].read()) # store the response bytes
    response_base64=response_byte['artifacts'][0]['base64'] #extract the artifacts into base 64
    resposne_image=base64.b64decode(response_base64) # decode the image
    image_name='images-'+ datetime.datetime.today().strftime('%Y-%M-%D-%H-%S') +'.jpg' # store the image name into date time format
  • Now we are going to put the generated image into S3 bucket and generate pre-signed URL:
 s3_response=s3_client.put_object(
        Bucket='', #replace it with your bucket name
        Body=resposne_image,
        Key=image_name
    )

    generate_url=s3_client.generate_presigned_url('get_object', Params={'Bucket':'<add your bucket here>','Key':image_name}, ExpiresIn=3600)

 return {
        'statusCode': 200,
        'body':generate_url
    }
  • Full code with Lambda function:
import json
import boto3
import base64
import datetime

bedrock_client = boto3.client('bedrock-runtime')
s3_client = boto3.client('s3')

def lambda_handler(event, context):
    input_text = event['prompt']
    print("Prompt:", input_text)  # for troubleshooting

    payload = {
        "text_prompts": [
            {
                "text": input_text
            }
        ],
        "height": 1024,
        "width": 1024,
        "cfg_scale": 7,
        "steps": 50,
        "style_preset": "photographic"
    }

    # Invoke Bedrock Model
    response = bedrock_client.invoke_model(
        body=json.dumps(payload),
        contentType='application/json',
        accept='application/json',
        modelId='stability.stable-diffusion-xl-v1'
    )

    response_body = json.loads(response['body'].read())
    response_base64 = response_body['artifacts'][0]['base64']
    response_image = base64.b64decode(response_base64)

    image_name = 'images-' + datetime.datetime.today().strftime('%Y-%m-%d-%H-%M-%S') + '.jpg'

    bucket_name = '<your-bucket-name>'  # <-- Replace this with your actual bucket name

    s3_client.put_object(
        Bucket=bucket_name,
        Body=response_image,
        Key=image_name,
        ContentType='image/jpeg'
    )

    generate_url = s3_client.generate_presigned_url(
        'get_object',
        Params={'Bucket': bucket_name, 'Key': image_name},
        ExpiresIn=3600  # URL expiration time in seconds
    )

    return {
        'statusCode': 200,
        'body': generate_url
    }

4. Create API Gateway

  1. Now to let's move to API Gateway, we are going to create REST API with any related name you want.
  2. Choose New API. Enter API name: stable-diffusion-bedrock-generative-image-api-gateway. API endpoint type:**** choose Regional. Choose button Create API.
  3. We will create a method GET. Click button Create method.
  4. Select your Lambda Function and make sure that the API gateway has permission to invoke the Lambda function.
  5. Make sure to modify the method request settings & URL query string parameters to be as below:
  6. The value here should be similar to the one in the code. Finally, click button Create method.
  7. Edit the mapping template in the integration request with the below values. Click tab Integration request -> Edit.
  8. In Request body passthrough: check Never. Click button Add mapping template.
  9. Content type: application/json. The template body, copy code template body with the below value:
{
"prompt":"$input.params('prompt')"
}
  1. Finally, click button Save.
  2. Now you are ready to Deploy your API and test it.
  3. You should now receive a pre-signed returned to the API Gateway
  4. The generated image should be something like this
  5. Example prompt: "A confident female weather presenter in a modern broadcast studio, wearing a striking red off-the-shoulder evening gown with a thigh-high slit, holding a tablet while standing in front of a large weather map showing temperatures and regions. Professional lighting, detailed, photorealistic, 4K resolution, cinematic style." :)))

5. Clean up resources