本文档旨在介绍如何通过一个简单的 Bash 脚本,使用 curl
命令调用 UIUI API 的 OpenAI 兼容对话接口。该脚本能够接收一张输入图片,并根据用户提供的文本提示(prompt)和指定的风格(例如动画风格),让OpenAI新版GPT-4o模型API Key生成一张新的图片,并将其下载到本地。
流程简介
准备工作 (Preparation):
- 在UIUIAPI.com获取您的 OpenAI GPT-4o API KEY的Token。
- 准备一张需要转换的源图片(支持
.jpg
或.png
格式)。 - 确保您的本地环境已安装并可运行 Bash 和
curl
命令。
脚本执行步骤 (Script Execution Steps):
- 脚本首先会检查输入的图片文件是否存在且格式是否为支持的
.jpg
或.png
。 - 将图片内容转换为 Base64 编码,以便嵌入 JSON 请求中。
- 提示用户输入文本提示(prompt),用于描述期望的生成效果。
- 构造包含文本提示和 Base64 图片数据的 JSON 请求体。
- 使用
curl
命令,将构造好的 JSON 数据发送到 uiui api 的/v1/chat/completions
对话接口。 - 由于 API 采用流式响应(stream),脚本会实时接收数据,并从中提取任务信息,直到检测到任务完成的标志(
finish_reason: stop
)。 - 任务完成后,脚本会从完整的响应数据中提取生成的图片 URL。
- 最后,使用
curl
下载该 URL 指向的图片,并保存到本地的output
目录。
输出 (Output):
- 生成的图片将保存在脚本同级目录下的
output
文件夹中,文件名为generated_image_时间戳.jpg
(时间戳格式为 YYYYMMDDHHMMSS)。
准备工作
-
获取 API Token:
- 访问 UIUI API Token 获取页面 (请替换为实际链接) 并创建一个新的 API Token。
- 复制生成的 API Token(通常以
sk-
开头)。稍后需要将此 Token 填入脚本中的API_KEY
变量处。
-
API 信息:
- API 基础地址:
https://sg.uiuiapi.com/v1
- 对话请求地址:
https://sg.uiuiapi.com/v1/chat/completions
- 支持的模型 (根据需求选择):
gpt-4o-all
:按 token 计费,价格便宜,用户较多。gpt-4o-image
:按次计费,价格便宜,用户较少。gpt-4o-image-vip
:按次计费,价格较高,用户最少。
- 请注意:本脚本默认使用
gpt-4o-image-vip
模型。您可以根据需要修改脚本中的model
字段来选择其他模型。
- API 基础地址:
-
环境要求:
- 确保您的操作系统支持运行 Bash 脚本(例如 Linux, macOS, 或 Windows Subsystem for Linux - WSL)。
- 确保已安装
curl
命令行工具。 - 确保您在脚本运行的目录下拥有创建文件夹(
output
)和文件的权限。
Bash 脚本实现
以下是完整的 Bash 脚本 (sub.sh
):
#!/bin/bash
# 前置检查和变量定义
IMAGE_FILE="$1"
OUTPUT_DIR="output"
API_URL="https://sg.uiuiapi.com/v1/chat/completions"
API_KEY="Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # <-- 在这里替换你的 API Token (sk- 开头的部分)
TEMP_JSON="/tmp/request.json"
RESPONSE_FILE="/tmp/response_stream.txt"
# 检查参数和文件
if [ $# -ne 1 ] || [ ! -f "$IMAGE_FILE" ] || [[ ! "$IMAGE_FILE" =~ \.(jpg|png)$ ]]; then
echo "用法: $0 <图片文件路径(.jpg 或 .png)>"
echo "示例: $0 my_image.png"
exit 1
fi
# 检查或创建输出目录
if [ ! -d "$OUTPUT_DIR" ]; then
mkdir "$OUTPUT_DIR"
if [ $? -ne 0 ]; then
echo "错误: 无法创建输出目录 '$OUTPUT_DIR'"
exit 1
fi
fi
# 转换图片为 base64
echo "正在将图片转换为 Base64 编码..."
BASE64_IMAGE=$(base64 < "$IMAGE_FILE" | tr -d '\n')
if [ -z "$BASE64_IMAGE" ]; then
echo "错误: 无法将图片转换为 Base64 编码。"
exit 1
fi
echo "图片 Base64 编码完成。"
# 获取用户输入的 prompt
echo "请输入你的 prompt (描述你希望如何处理图片):"
read -r PROMPT
if [ -z "$PROMPT" ]; then
echo "错误: prompt 不能为空。"
exit 1
fi
# 构造 JSON 数据
# 注意: "url": "data:image/jpeg;base64,$BASE64_IMAGE" - 即使输入是png,这里也用jpeg作为mime类型示例,
# OpenAI API 通常能自动处理。如果遇到问题,可以尝试根据输入文件动态调整 mime 类型。
JSON_DATA=$(cat <<EOF
{
"model": "gpt-4o-image-vip",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "$PROMPT"
},
{
"type": "image_url",
"image_url": {
"url": "data:image/jpeg;base64,$BASE64_IMAGE"
}
}
]
}
],
"n_tokens": 3000,
"stream": true
}
EOF
)
# 将 JSON 数据写入临时文件
echo "$JSON_DATA" > "$TEMP_JSON"
if [ $? -ne 0 ]; then
echo "错误: 无法写入临时 JSON 文件 '$TEMP_JSON'"
exit 1
fi
echo "请求 JSON 数据已准备好。"
# 实时处理流式响应并保存到文件
echo "正在调用 API 提交任务 (请耐心等待)..."
# 清空之前的响应记录文件
> "$RESPONSE_FILE"
# 使用 curl 调用 API,通过 tee 同时输出到控制台和文件,然后用 while 循环处理每一行
curl -s -N -H "Authorization: $API_KEY" \
-H "Content-Type: application/json" \
-d "@$TEMP_JSON" \
--no-buffer \
"$API_URL" | tee -a "$RESPONSE_FILE" | while IFS= read -r line; do
# 显示当前行,便于监控 (可以注释掉以减少输出)
# echo "API Raw Line: $line"
# 尝试从流式数据中提取并显示进度信息
# uiui-Zi API 可能以特定格式返回进度,这里假设它在 content 中包含 "> 进度 xx%"
if [[ "$line" == *"data:"* ]]; then
# 提取 data 部分的 JSON 内容
DATA_JSON=$(echo "$line" | sed 's/^data: //')
# 尝试提取 content 中的进度
PROGRESS_INFO=$(echo "$DATA_JSON" | grep -o '"content":"[^"]* > 进度 [0-9]*%[^"]*"' | sed -e 's/.* > 进度 //' -e 's/%".*//')
if [[ -n "$PROGRESS_INFO" ]]; then
printf "\r任务进度: %s%%" "$PROGRESS_INFO"
fi
# 检查 finish_reason
FINISH_REASON=$(echo "$DATA_JSON" | grep -o '"finish_reason":"[^"]*"' | sed 's/"finish_reason":"http://;s/"http://')
if [ "$FINISH_REASON" = "stop" ]; then
echo -e "\n任务已完成!(finish_reason: $FINISH_REASON)"
# 确保循环能够正常退出
kill $$ # 发送 SIGTERM 信号给当前脚本进程,以跳出 read 循环
break # 虽然 kill 通常能结束,保留 break 作为备用
elif [ -n "$FINISH_REASON" ] && [ "$FINISH_REASON" != "null" ]; then
echo -e "\n任务异常结束!(finish_reason: $FINISH_REASON)"
# 可以在这里添加错误处理逻辑
kill $$
break
fi
elif [[ "$line" == *"[DONE]"* ]]; then
# 有些流式API最后会发送 [DONE]
echo -e "\n检测到流结束标志 [DONE]。"
# 此时 finish_reason 可能在之前的行中,或者需要检查整个文件
# 再次检查文件末尾是否有 stop 标志,以防万一
if ! grep -q '"finish_reason":"stop"' "$RESPONSE_FILE"; then
echo "警告: 检测到 [DONE] 但未找到明确的 'stop' 标志,尝试继续提取 URL。"
fi
kill $$
break
elif [[ "$line" == *"error"* ]]; then
# 捕获明显的错误信息
echo -e "\n错误: API 返回错误信息: $line"
kill $$
break
fi
done
# 等待 curl 进程结束(如果 kill 信号生效,这里可能不需要)
wait $! 2>/dev/null
# 检查循环退出状态和响应内容
echo "流式响应处理完毕,正在分析结果..."
if ! grep -q '"finish_reason":"stop"' "$RESPONSE_FILE"; then
echo "错误: API 调用似乎未成功完成或未在响应流中检测到 'finish_reason: stop' 标志。"
echo "部分响应内容如下 (保存于 $RESPONSE_FILE):"
tail -n 10 "$RESPONSE_FILE" # 显示最后几行帮助调试
rm -f "$TEMP_JSON" # 保留 RESPONSE_FILE 供调试
exit 1
fi
# 从完整响应中提取图像 URL
# uiui API 返回的图片 URL 可能在 content 字段的 Markdown 格式中
echo "正在从响应数据中提取图像 URL..."
# 使用 grep 和 sed 提取 Markdown 图片链接中的 URL
IMAGE_URL=$(grep -o '!\[.*\](https://[^)]*)' "$RESPONSE_FILE" | sed 's/.*(//;s/)//' | head -n 1)
if [ -z "$IMAGE_URL" ]; then
echo "错误: 无法从 API 响应中提取有效的图像 URL。"
echo "请检查临时文件 '$RESPONSE_FILE' 以获取详细响应。"
# cat "$RESPONSE_FILE" # 可以取消注释以显示完整响应
rm -f "$TEMP_JSON" # 保留 RESPONSE_FILE 供调试
exit 1
fi
echo "提取到图像 URL: $IMAGE_URL"
# 下载图片
TIMESTAMP=$(date +%Y%m%d%H%M%S)
OUTPUT_FILE="$OUTPUT_DIR/generated_image_$TIMESTAMP.jpg"
echo "正在下载图片到 $OUTPUT_FILE..."
curl -s -L -o "$OUTPUT_FILE" "$IMAGE_URL" # 添加 -L 以处理可能的重定向
if [ $? -eq 0 ] && [ -s "$OUTPUT_FILE" ]; then
echo "图片已成功下载到 $OUTPUT_FILE"
else
echo "错误: 图片下载失败或下载的文件为空。"
# 可以尝试再次打印 URL 或检查网络连接
echo "URL: $IMAGE_URL"
rm -f "$TEMP_JSON" # 保留 RESPONSE_FILE 供调试
exit 1
fi
# 清理临时文件
echo "清理临时文件..."
rm -f "$TEMP_JSON" "$RESPONSE_FILE"
echo "脚本执行完毕。"
exit 0
脚本使用方法
-
准备输入图片:
- 准备一张您想要转换的图片(例如
plot.png
或photo.jpg
),并将其放置在与sub.sh
脚本相同的目录下。
- 准备一张您想要转换的图片(例如
-
OpenAI api key获取替换 API Token:
- 使用文本编辑器打开
sub.sh
文件。 - 找到以下这行:
API_KEY="Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- 将
sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
替换为您从 UIUIAPI.com 平台获取的真实 API Token。请确保Bearer
前缀保留。
- 使用文本编辑器打开
-
运行脚本:
- 打开终端,确保您位于
sub.sh
和图片文件所在的目录。 - 运行脚本,并将图片的文件名作为第一个参数传递给它:
(请将./sub.sh plot.png
plot.png
替换为您实际的图片文件名) - 脚本启动后,会提示您输入 prompt:
请输入你的 prompt (描述你希望如何处理图片):
- 输入您希望的描述,例如:
或者更具体的:把它转化为动画的风格
Convert this image to an anime style, vibrant colors, clean lines.
- 按下回车键。脚本将开始向 UIUI API 提交任务。您会看到类似以下的输出,显示任务提交和进度信息(如果 API 返回进度的话):
正在将图片转换为 Base64 编码... 图片 Base64 编码完成。 请输入你的 prompt (描述你希望如何处理图片): 把它转化为动画的风格 请求 JSON 数据已准备好。 正在调用 API 提交任务 (请耐心等待)... 任务进度: 10% 任务进度: 50% 任务进度: 90% 任务已完成!(finish_reason: stop) 流式响应处理完毕,正在分析结果... 正在从响应数据中提取图像 URL... 提取到图像 正在下载图片到 output/generated_image_20250330123456.jpg... 图片已成功下载到 output/generated_image_20250330123456.jpg 清理临时文件... 脚本执行完毕。
- 打开终端,确保您位于
-
查看结果:
- 脚本成功执行后,会在当前目录下创建一个名为
output
的文件夹(如果尚不存在)。 - 生成的图片将保存在
output
文件夹内,文件名类似于generated_image_20250330123456.jpg
。 - 打开
output
目录,您就可以查看生成的图片了。
- 脚本成功执行后,会在当前目录下创建一个名为
示例:生成吉卜力风格图片
假设您有一张名为 landscape.jpg
的风景照片,希望将其转换为吉卜力工作室的动画风格。
- 将
landscape.jpg
放在与sub.sh
相同的目录下。 - 确保已在
sub.sh
中填入正确的 API Token。 - 运行脚本:
./sub.sh landscape.jpg
- 当提示输入 prompt 时,输入:
请将这张图片转化为吉卜力动画风格,保持原始构图,色彩柔和。
- 等待脚本执行完成。生成的吉卜力风格图片将保存在
output
目录中。
总结
本文档提供了一个使用 Bash 脚本和 curl
命令的 OpenAI 兼容对话接口进行交互,以实现图片风格转换的实用示例。通过简单的步骤,用户可以准备环境、配置脚本,并根据文本提示将本地图片转换为所需风格,最终将结果下载保存。该脚本利用了流式 API 响应处理,并包含了基本的错误检查和用户交互。用户可以根据自身需求,修改脚本中的模型选择、错误处理逻辑或输出格式。
點(diǎn)擊查看更多內(nèi)容
1人點(diǎn)贊
評(píng)論
評(píng)論
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章
正在加載中
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦