Python| 如何使用 DALL·E 和 OpenAI API 生成图像(2)
## 引言想象一下,只要描述你想要的画面,电脑就能帮你画出来。这在几年前还像是科幻小说里的场景,但随着神经网络和潜在扩散模型(LDM)技术的发展,现在已经成为可能。OpenAI 推出的 DALL·E 工具,因其能生成令人惊叹的艺术作品和逼真的图像而广受欢迎。
你可以通过 OpenAI 的 API 访问 DALL·E,这样你就可以将它的功能集成到你的 Python 程序中。
[本教程](https://realpython.com/generate-images-with-dalle-openai-api/ "Source")将带你:
- 快速上手 OpenAI 的 Python 库
- 探索与图像生成相关的 API 调用
- 根据文本提示生成图像
- 制作生成图像的不同版本
- 将 Base64 格式的 JSON 响应转换成 PNG 图像文件
## 将图像数据保存到文件
虽然利用 Python、DALL·E 和 OpenAI API 从文本生成图像非常酷,但目前得到的响应是临时的。如果你想在 Python 脚本中继续使用这些生成的图像,最好是跳过 URL,直接获取图像数据:
```python
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.b64_json[:50])
```
API 提供了一个选项,允许你将响应格式从 URL 改为 Base64 编码的图像数据。在脚本的第 12 行,你通过设置 `response_format` 参数为 "b64_json" 来实现这一点。这个参数的默认设置是 "url",这也是为什么你之前收到的 JSON 响应中包含的是 URL。
尽管你修改后的 JSON 响应在外观上与之前类似,但获取图像数据的键值已经从 "url" 变为了 "b64_json"。你在第 15 行的 `print()` 函数调用中应用了这一更改,并且只输出了前五十个字符。
如果你使用这些设置来执行脚本,你将获得生成图像的实际数据。但是,先别急着运行脚本,因为一旦脚本执行完毕,图像数据就会立即丢失,你将无法查看到图像!
为了防止丢失那个完美的图像,你可以选择将 JSON 响应保存到文件中,而不是仅仅将其打印到终端上:
```python
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 中实现这一点并不需要太多的代码,所以请继续创建一个新的脚本文件来完成这项转换:
```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 文件,最终一睹你期待已久的理想生成图像。
![](data/attachment/forum/plugin_zhanmishu_markdown/202410/9a1a9c6bc5078e30a3f54f0d6eefd27c_1728904940_1765.png)
这符合你所有的期望吗?如果答案是肯定的,那就太棒了!但如果得到的图像与你要找的差不多,但又不完全一样,那么你可以通过 API 再次提交你的图像作为输入,并创建它的一些变体。
## 创建图像的变体
如果你手头有一张图像——无论它是机器生成的还是其他来源——它与你想要的相似,但又不完全符合要求,那么你可以利用 OpenAI 的 DALL·E 2 潜在扩散模型来创建它的变体。
基于你在本教程中早先编写的代码,你可以创建一个名为 vary.py 的新文件:
```python
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"]["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`,然后运行转换脚本,查看你的图像变体。
您的图像变化看起来如何?也许其中之一最适合您正在寻找的东西:
![](https://s2.loli.net/2024/10/08/NitzKHR5ELGQ72l.png)
如果你对其中一张图像感到满意,但它仍未完全达到你的期望,那么你可以通过修改 `vary.py` 中的 `SOURCE_FILE` 值再次运行脚本。如果你想基于第一张以外的其他图像来创建变体,你还需要更改你想要使用的图像数据的索引。
## 总结
幻想拥有既环保又具有出色美学的电脑固然有趣 - - 但更棒的是,通过使用 Python 和 OpenAI 的 Images API 来实现这些图像的创造!
在本教程中,你已经学会了:
- 如何在本地安装配置 OpenAI Python 库
- 如何利用 OpenAI API 的图像生成功能
- 如何使用 Python 根据文本提示生成图像
- 如何制作生成图像的变体
- 如何将 Base64 JSON 响应转换为 PNG 图像文件
最重要的是,你获得了将 API 调用整合到你的 Python 脚本中的实际经验,这使你能够将令人惊叹的图像创造功能带入你自己的应用中。
页:
[1]