引言
想象一下,只要描述你想要的画面,电脑就能帮你画出来。这在几年前还像是科幻小说里的场景,但随着神经网络和潜在扩散模型(LDM)技术的发展,现在已经成为可能。OpenAI 推出的 DALL·E 工具,因其能生成令人惊叹的艺术作品和逼真的图像而广受欢迎。
你可以通过 OpenAI 的 API 访问 DALL·E,这样你就可以将它的功能集成到你的 Python 程序中。
本教程将带你:
- 快速上手 OpenAI 的 Python 库
- 探索与图像生成相关的 API 调用
- 根据文本提示生成图像
- 制作生成图像的不同版本
- 将 Base64 格式的 JSON 响应转换成 PNG 图像文件
将图像数据保存到文件
虽然利用 Python、DALL·E 和 OpenAI API 从文本生成图像非常酷,但目前得到的响应是临时的。如果你想在 Python 脚本中继续使用这些生成的图像,最好是跳过 URL,直接获取图像数据:
from openai import OpenAI
client = OpenAI()
PROMPT = "An eco-friendly computer from the 90s in the style of vaporwave"
response = client.images.generate(
model="dall-e-2",
prompt=PROMPT,
n=1,
size="256x256",
response_format="b64_json",
)
print(response.data[0].b64_json[:50])
API 提供了一个选项,允许你将响应格式从 URL 改为 Base64 编码的图像数据。在脚本的第 12 行,你通过设置 response_format
参数为 "b64_json" 来实现这一点。这个参数的默认设置是 "url",这也是为什么你之前收到的 JSON 响应中包含的是 URL。
尽管你修改后的 JSON 响应在外观上与之前类似,但获取图像数据的键值已经从 "url" 变为了 "b64_json"。你在第 15 行的 print()
函数调用中应用了这一更改,并且只输出了前五十个字符。
如果你使用这些设置来执行脚本,你将获得生成图像的实际数据。但是,先别急着运行脚本,因为一旦脚本执行完毕,图像数据就会立即丢失,你将无法查看到图像!
为了防止丢失那个完美的图像,你可以选择将 JSON 响应保存到文件中,而不是仅仅将其打印到终端上:
import json
from pathlib import Path
from openai import OpenAI
client = OpenAI()
PROMPT = "An eco-friendly computer from the 90s in the style of vaporwave"
DATA_DIR = Path.cwd() / "responses"
DATA_DIR.mkdir(exist_ok=True)
response = client.images.generate(
model="dall-e-2",
prompt=PROMPT,
n=1,
size="256x256",
response_format="b64_json",
)
file_name = DATA_DIR / f"{PROMPT[:5]}-{response.created}.json"
with open(file_name, mode="w", encoding="utf-8") as file:
json.dump(response.to_dict(), file)
通过几行额外的代码,你利用 pathlib
和 json
模块在你的 Python 脚本中实现了文件操作功能:
第 9 行和第 11 行定义并创建了一个名为 "responses/" 的文件夹,用来存储 API 响应的 JSON 文件。
第 21 行设定了一个变量,用于指定你想要保存数据的文件路径。你结合了提示的开头和 JSON 响应中的时间戳来生成一个独特的文件名。
第 23 行和第 24 行在数据文件夹中创建了一个新的 JSON 文件,并将 API 响应以 JSON 格式写入该文件。
有了这些新增的功能,你现在可以运行你的脚本来生成图像,并且图像数据会被妥善保存在你数据文件夹内的一个特定文件中。
你是否已经运行了脚本并检查了生成的 JSON 文件?看起来像天书,对吧?那么,你确定由 DALL·E 创建的那张最佳图像在哪里呢?
它就在那里,只是目前它是以 Base64 编码的形式存在的,这对于人类来说可不太方便查看。在下一节中,你将学习如何将 Base64 编码的图像数据转换成 PNG 文件,这样你就可以直接查看了。
解码 Base64 编码的 JSON 响应
你刚刚已经将一个 PNG 图像以 Base64 编码的字符串形式保存在了 JSON 文件中。这很棒,因为它意味着你的图像不会在互联网上消失,这与你持续通过 API 调用生成 URL 的情况不同。
然而,现在你无法查看你的图像——除非你学会如何解码这些数据。幸运的是,在 Python 中实现这一点并不需要太多的代码,所以请继续创建一个新的脚本文件来完成这项转换:
import json
from base64 import b64decode
from pathlib import Path
DATA_DIR = Path.cwd() / "responses"
JSON_FILE = DATA_DIR / "An ec-1667994848.json"
IMAGE_DIR = Path.cwd() / "images" / JSON_FILE.stem
IMAGE_DIR.mkdir(parents=True, exist_ok=True)
with open(JSON_FILE, mode="r", encoding="utf-8") as file:
response = json.load(file)
for index, image_dict in enumerate(response["data"]):
image_data = b64decode(image_dict["b64_json"])
image_file = IMAGE_DIR / f"{JSON_FILE.stem}-{index}.png"
with open(image_file, mode="wb") as png:
png.write(image_data)
convert.py
脚本将读取你在变量 JSON_FILE
中指定的 JSON 文件名。请记得,你需要根据你的 JSON 文件的实际名字来调整 JSON_FILE
的值。
接下来,脚本会从 JSON 数据中提取 Base64 编码的字符串,解码它,并将解码后的图像数据保存为 PNG 文件到指定目录。如果目录不存在,Python 会为你创建它。
请注意,即使你一次获取多张图片,这个脚本同样有效。for 循环会逐个解码每张图片并分别保存为新文件。
提示:如果你想生成包含多张图片 Base64 编码数据的 JSON 文件,可以在运行 create.py
脚本时,将参数 n
的值设置为大于 1 的数字。
这个脚本的大部分代码都涉及从正确的文件夹中读取和写入文件。真正的亮点是 b64decode()
函数。你在第 2 行导入了这个函数,并在第 15 行使用它来解码 Base64 编码的字符串,以便将实际的图像数据保存为 PNG 文件。这样,你的计算机就能识别出 PNG 图像格式,并知道如何将其显示给你。
运行脚本后,你可以前往新创建的文件夹结构,打开 PNG 文件,最终一睹你期待已久的理想生成图像。
这符合你所有的期望吗?如果答案是肯定的,那就太棒了!但如果得到的图像与你要找的差不多,但又不完全一样,那么你可以通过 API 再次提交你的图像作为输入,并创建它的一些变体。
创建图像的变体
如果你手头有一张图像——无论它是机器生成的还是其他来源——它与你想要的相似,但又不完全符合要求,那么你可以利用 OpenAI 的 DALL·E 2 潜在扩散模型来创建它的变体。
基于你在本教程中早先编写的代码,你可以创建一个名为 vary.py 的新文件:
import json
from base64 import b64decode
from pathlib import Path
from openai import OpenAI
client = OpenAI()
DATA_DIR = Path.cwd() / "responses"
SOURCE_FILE = DATA_DIR / "An ec-1667994848.json"
with open(SOURCE_FILE, mode="r", encoding="utf-8") as json_file:
saved_response = json.load(json_file)
image_data = b64decode(saved_response["data"][0]["b64_json"])
response = client.images.create_variation(
image=image_data,
n=3,
size="256x256",
response_format="b64_json",
)
new_file_name = f"vary-{SOURCE_FILE.stem[:5]}-{response.created}.json"
with open(DATA_DIR / new_file_name, mode="w", encoding="utf-8") as file:
json.dump(response.to_dict(), file)
在该脚本中,你将之前 JSON 响应中的 Base64 编码图像数据发送到 Images API,并请求生成该图像的三个变体。然后,你将这三个变体图像的数据保存在你数据目录下的一个新 JSON 文件中:
第 10 行设定了一个常量,该常量指定了包含你想要生成变体的图像 Base64 编码数据的 JSON 文件名。如果你希望为另一张不同的图像创建变体,你需要在重新执行脚本前修改这个常量。
第 14 行使用 b64decode()
函数解码图像数据,与在 convert.py
中的操作相同,并将解码后的数据保存到 image_data
中。请注意,代码默认选取了 JSON 文件中的第一张图像。如果你保存的响应中包含多张图像,且你希望基于另一张图像来创建变体,你需要相应地调整索引值。
第 17 行将 image_data
作为参数传递给 .create_variation()
方法。注意,该方法的 image
参数需要有效的 PNG 图像数据,这也是为什么你需要在将 JSON 响应中的字符串传递给方法之前先对其进行解码。
第 18 行设定了你希望获得的原始图像变体的数量。在这里,你将 n
设置为 3,意味着你将得到三张新的变体图像。
如果你查看你的 responses/
目录,你将看到一个新的 JSON 文件,其名称以 vary-
开头。这个文件包含了你的新图像变体的数据。你可以复制这个文件名,并在 convert.py
中将其设置为 JSON_FILE
,然后运行转换脚本,查看你的图像变体。
您的图像变化看起来如何?也许其中之一最适合您正在寻找的东西:
如果你对其中一张图像感到满意,但它仍未完全达到你的期望,那么你可以通过修改 vary.py
中的 SOURCE_FILE
值再次运行脚本。如果你想基于第一张以外的其他图像来创建变体,你还需要更改你想要使用的图像数据的索引。
总结
幻想拥有既环保又具有出色美学的电脑固然有趣 - - 但更棒的是,通过使用 Python 和 OpenAI 的 Images API 来实现这些图像的创造!
在本教程中,你已经学会了:
- 如何在本地安装配置 OpenAI Python 库
- 如何利用 OpenAI API 的图像生成功能
- 如何使用 Python 根据文本提示生成图像
- 如何制作生成图像的变体
- 如何将 Base64 JSON 响应转换为 PNG 图像文件
最重要的是,你获得了将 API 调用整合到你的 Python 脚本中的实际经验,这使你能够将令人惊叹的图像创造功能带入你自己的应用中。