iT邦幫忙

2025 iThome 鐵人賽

DAY 6
0
生成式 AI

練習AI系列 第 7

文字生成圖片 (Text-to-Image)

  • 分享至 

  • xImage
  •  

🆕 程式碼實作

  1. src/day6_text_to_image.js(新增)
    // src/day6_text_to_image.js
    import { openai } from "./aiClient.js";
    import fs from "fs";
    import path from "path";

/**

  • 文字轉圖片
  • @param {string} prompt - 描述(文字)
  • @param {object} opts
  • @param {string} [opts.size="512x512"] - 可選 256x256 | 512x512 | 1024x1024
  • @param {number} [opts.n=1] - 生成圖片數量
  • @param {string} [opts.outputDir="outputs/images"]
    */
    export async function textToImage(prompt, opts = {}) {
    const {
    size = "512x512",
    n = 1,
    outputDir = "outputs/images",
    } = opts;

if (!prompt) throw new Error("必須提供 prompt");

const res = await openai.images.generate({
model: "gpt-image-1",
prompt,
size,
n,
});

if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });

const urls = [];
for (let i = 0; i < res.data.length; i++) {
const b64 = res.data[i].b64_json;
const buf = Buffer.from(b64, "base64");
const filename = path.join(outputDir, img_${Date.now()}_${i + 1}.png);
fs.writeFileSync(filename, buf);
urls.push(filename);
}

return urls;
}

  1. index.js(修改)
    // index.js
    import { englishTeacher, codeReview, sentimentClassify } from "./src/day3_prompt_engineering.js";
    import { newsToJson } from "./src/day4_text_to_json.js";
    import { chatOnce, resetSession } from "./src/day5_chat_history.js";
    import { textToImage } from "./src/day6_text_to_image.js";

const args = Object.fromEntries(
process.argv.slice(2).reduce((acc, cur, i, arr) => {
if (cur.startsWith("--")) {
const key = cur.replace(/^--/, "");
const val = arr[i + 1] && !arr[i + 1].startsWith("--") ? arr[i + 1] : true;
acc.push([key, val]);
}
return acc;
}, [])
);

async function main() {
const task = args.task || "chat";

if (task === "image") {
const prompt = args.text || "一隻戴著太空頭盔的柴犬,漂浮在月球上,插著台灣國旗";
const size = args.size || "512x512";
const n = args.n ? Number(args.n) : 1;
const urls = await textToImage(prompt, { size, n });
console.log("\n=== 生成圖片 ===\n");
urls.forEach((f) => console.log("已儲存:" + f));

} else if (task === "chat") {
const sessionId = args.session || "default";
if (args.reset) {
resetSession(sessionId);
console.log(已重設會話:${sessionId});
return;
}
const input = args.text || "嗨,我想規劃 3 天 2 夜的台中旅遊行程。";
const { reply } = await chatOnce(input, { sessionId });
console.log(\n[${sessionId}] AI:\n${reply}\n);

} else if (task === "teacher") {
const out = await englishTeacher(args.text || "He go to school every day.");
console.log("\n=== 英文老師 ===\n");
console.log(out);

} else if (task === "review") {
const out = await codeReview("function sum(arr){ return arr.reduce((a,b)=>a+b,0) }");
console.log("\n=== 程式碼審查 ===\n");
console.log(out);

} else if (task === "sentiment") {
const out = await sentimentClassify(args.text || "今天心情糟透了,事情一團亂。");
console.log("\n=== 情緒分類(JSON) ===\n");
console.log(out);

} else if (task === "json_summary") {
const out = await newsToJson(args.text || "OpenAI 發布新模型,效能大幅提升。");
console.log("\n=== 新聞 JSON 摘要 ===\n");
console.log(out);

} else {
console.log("未知任務,請使用 --task chat | teacher | review | sentiment | json_summary | image");
}
}

main().catch((e) => {
console.error("發生錯誤:", e.message);
process.exit(1);
});

  1. package.json(新增 Script)
    {
    "scripts": {
    "day6:image": "node index.js --task image --text "一個賽博龐克風格的台北 101 夜景" --size 512x512"
    }
    }

▶️ 執行方式

產生一張 512x512 的圖片

npm run day6:image --silent

產生 2 張 1024x1024 的圖片

node index.js --task image --text "復古漫畫風格的 AI 機器人" --size 1024x1024 --n 2

會在 outputs/images/ 生成檔案,例如:

outputs/images/img_1726123456789_1.png
outputs/images/img_1726123456789_2.png


上一篇
多輪對話(Chat History)
下一篇
圖片描述 (Image-to-Text)
系列文
練習AI11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言