在本系列的上篇中,我们介绍了如何利用Amazon Nova Canvas进行创意图片内容生成,并使用Amazon Bedrock的InvokeModel API进行文本到图像(文生图)的生成。并且介绍了Nova Canvas提供的广泛的功能,包括图像修复、画布扩展、颜色引导等,使其成为强大的AI创意工具。接下来下篇中我们将继续介绍我们上篇中的方案,利用Nova生成一个完整的故事书插画。
调整Nova Canvas的生成结果
编辑提示词(Edit Prompt)
如果生成的图像没有达到预期,或者缺少某些特征,可以通过修改提示词(prompt)来调整结果。例如:
prompt = """
A rundown house with a light, the front door of the house is swung wide open
and a warm fire in a chimney can be seen.
"""
重新运行代码后,会生成符合新描述的图像。
修改随机种子(Change Seed)
如果当前提示词生成的图像不错,但想要探索一些变化,可以更改种子值(seed),以生成不同版本的图像:
seed: 23423423
这将创建一个具有相似风格但不同细节的新图像。
调整cfgScale参数
如果模型生成的图像未能严格按照提示词执行,大家可以调整 cfgScale
参数:
cfgScale: 8.5
- 值越高(最大10.0):模型会更加严格遵循提示词的描述。
- 值越低(最小1.1):生成的图像会带有更多随机性,可能出现创造性的变化。
负面提示词(Negative Text )
如果想要去除特定元素,可以使用 negativeText
属性。例如,要生成一张没有窗户的房屋:
negative_prompt = "window, window with light"# ..."textToImageParams": {"text": prompt,"negativeText": negative_prompt
},
这将告诉模型不要生成包含这些元素的图片,再次运行将生成以下图片。
大家现在已经掌握了调整Nova Canvas输出的各种方法,包括修改提示词、调整随机种子、配置cfgScale参数,以及使用负面提示词去除特定元素。
如需了解更多关于提示词优化(Prompt Optimization)和输出调整(Output Tweaking)的详细信息,请参考Nova官方文档。
生成最终输出 - 故事板(Storyboard)
现在,大家已经掌握了Nova Canvas的调整技巧,接下来可以继续生成多个图像,并把他们组合生成PDF故事图画集。
大家可以选择一个故事情节,设计图片分镜布局,然后使用Python代码自动生成一个故事图画集,并导出为单页PDF。
更新 requirements.txt
请确保 requirements.txt 文件包含以下依赖项:
boto3
fpdf2
在本地 IDE 或 SageMaker Jupyter Notebook 安装依赖
如果大家使用的是SageMaker Jupyter Notebook,可以在Notebook的第一个代码单元格中运行:
!pip install boto3
!pip install fpdf2
代码示例
该代码将会生成一个完整的故事图画集PDF,包含三幅由Nova Canvas生成的插图。
# Required imports
import base64
import io
import json
import boto3
from PIL import Image
from botocore.config import Config
import time
from fpdf import FPDF# Create the client instance (5 minute timeout)
bedrock = boto3.client(service_name='bedrock-runtime',region_name="us-east-1",config=Config(read_timeout=300)
)# Define the default generated image width and height
DEFAULT_IMG_WIDTH = 480
DEFAULT_IMG_HEIGHT = 480# Cells are used for page layout, this is the size of one cell
CELL_WIDTH = DEFAULT_IMG_WIDTH / 6# Define a page layout of cells, 1 or 2 cell spans per row, 3 rows per page
page_layout = [[7,5], [12], [8,4]]# Define the story for each cell
story = ["""Two bears entering a dark, ominous wood, walking along a grassy path. Seen from behind.""","""Two bears in a dark, ominous wood, a small, rundown house with a light on is in front of them. Seen from behind.""","""A rundown house with a light, the door of the house is open and a warm fire and pot can be seen through the door.""","""A rundown house with a light, the door of the house is open and a warm fire and pot can be seen through the door. A shadowy figure is standing at the door""","""A rundown house with a light, the door of the house is open and a warm fire and pot can be seen through the door. A man is standing at the door with an axe. Two bears are running from the house towards the viewer."""
]def image_from_text(text, width, height, file):body = json.dumps({"taskType": "TEXT_IMAGE","textToImageParams": {"text": text},"imageGenerationConfig": {"numberOfImages": 1,"width": width,"height": height,"cfgScale": 8.0,"seed": 0}})response = bedrock.invoke_model(body=body, modelId="amazon.nova-canvas-v1:0", accept="application/json", contentType="application/json")response_body = json.loads(response.get("body").read())base64_image = response_body.get("images")[0]base64_bytes = base64_image.encode('ascii')image_bytes = base64.b64decode(base64_bytes)image = Image.open(io.BytesIO(image_bytes))image.save(file)return filedef generate_story(story, page_layout):outputs = []cells = [cell for row in page_layout for cell in row]for idx, text in enumerate(story):if idx > 0:time.sleep(20)file = image_from_text(text, int(CELL_WIDTH * cells[idx]), DEFAULT_IMG_HEIGHT, f"story-{idx}.jpg")outputs.append(file)return outputsdef build_pdf(images, page_layout, file):pdf = FPDF(orientation="portrait")pdf.set_margin(0)pdf.add_page()row_height = pdf.eph / len(page_layout)cell_width = pdf.epw / 12print(f"{pdf.epw} {cell_width} {cell_width*7}")# full page height, half page width pdf.epw/2img_idx = 0for r_idx, row in enumerate(page_layout): cursor_y = r_idx * row_heightfor c_idx, cell in enumerate(row): cursor_x = 0 if c_idx == 0 else cell_width * row[c_idx - 1]pdf.set_y(cursor_y)pdf.image(images[img_idx], h=row_height, w=cell_width * cell, x=cursor_x) img_idx += 1pdf.output(file)images = generate_story(story, page_layout)
build_pdf(images, page_layout, "storyboard.pdf")
Nova模型生成的完整故事图片故事集如下:
调整图片生成风格
假如客户对以上的生成结果很满意,但建议将风格修改为卡通风格。我们可以再次利用Nova Canvas,以内可以通过其调整提示词实现不同的图像风格。
我们修改如下代码中的修改提示词部分,再次运行生成图片。
# ...
# existing code from previous exampledef generate_story_with_style(style, story, page_layout, prefix):outputs = []cells = [cell for row in page_layout for cell in row]for idx, text in enumerate(story):if idx > 0:time.sleep(20)file = image_from_text(style + text, int(CELL_WIDTH * cells[idx]), DEFAULT_IMG_HEIGHT, f"{prefix}-story-{idx}.jpg")outputs.append(file)return outputsstyle = "A cartoon style image. "
prefix="cartoon"styled_images = generate_story_with_style(style, story, page_layout, prefix)
build_pdf(styled_images, page_layout, f"{prefix}-storyboard.pdf")
然后重新运行脚本,便可以生成卡通化的故事图片集。
结论
- Nova Canvas提供了多种方法调整生成的图像,包括修改提示词、调整种子值、配置
cfgScale
以及负面提示词。 - 可以批量生成图像,并将其组合成PDF故事图片集,用于快速展示电影、产品、图像、文本等方面的创意概念。
- 可通过修改提示词风格(如"cartoon style")来快速匹配客户的不同图片生成需求。
通过Nova以上强大的功能,我们就可以仅需几秒就可以生成高质量的图片故事集,极大提高在商品海报、活动营销策划、产品概念展示等方面的工作效率。