요즘 AI가 유행이죠? 저도 알아요요
This commit is contained in:
parent
8399ce4107
commit
0017a3eb16
6 changed files with 122 additions and 15 deletions
|
|
@ -1,13 +1,14 @@
|
|||
import path from "path";
|
||||
import { join } from "path";
|
||||
import { createCanvas, loadImage, GlobalFonts } from "@napi-rs/canvas";
|
||||
import { getMealInfo } from "./meal"; // 이 함수의 내용은 제공되지 않았으므로 그대로 둡니다.
|
||||
import { getMealInfo, NameToEmoji } from "./meal"; // 이 함수의 내용은 제공되지 않았으므로 그대로 둡니다.
|
||||
import { getAllSchedules } from "./schedule";
|
||||
|
||||
GlobalFonts.registerFromPath('./template/Pretendard-Bold.ttf', 'Pretendard Bold')
|
||||
GlobalFonts.registerFromPath('./template/NotoColorEmoji-Regular.ttf', 'NotoColorEmoji Regular')
|
||||
|
||||
export class CreateImage {
|
||||
static async PostMeal(MLSV_YMD: string) {
|
||||
static async PostMeal(MLSV_YMD: string): Promise<void> {
|
||||
const mealInfo = await getMealInfo(MLSV_YMD);
|
||||
const img = await loadImage(path.join("./template/skeleton.png"));
|
||||
const canvas = createCanvas(img.width, img.height);
|
||||
|
|
@ -19,9 +20,23 @@ export class CreateImage {
|
|||
ctx.textAlign = "left";
|
||||
|
||||
const lines = mealInfo.meal.split("\n").reverse();
|
||||
lines.forEach((line, i) => {
|
||||
ctx.fillText(line, 75, 930 - i * 60);
|
||||
});
|
||||
let emojis = (await NameToEmoji(lines.toString())).split(",");
|
||||
console.log(emojis);
|
||||
if (lines.length !== emojis.length) {
|
||||
console.error("Error: Emojis and lines count mismatch retrying...");
|
||||
return this.PostMeal(MLSV_YMD);
|
||||
}
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const emoji = emojis[i];
|
||||
const text = lines[i];
|
||||
|
||||
ctx.font = "50px NotoColorEmoji Regular";
|
||||
ctx.fillText(emoji ?? "", 75, 930 - i * 60);
|
||||
|
||||
ctx.font = "56px Pretendard Bold";
|
||||
ctx.fillText(text ?? "", 75 + 80, 930 - i * 60);
|
||||
}
|
||||
|
||||
ctx.font = "24px Pretendard Bold";
|
||||
ctx.textAlign = "right";
|
||||
|
|
@ -138,7 +153,9 @@ export class CreateImage {
|
|||
|
||||
ctx.drawImage(img, offsetX, offsetY, resizedWidth, resizedHeight);
|
||||
|
||||
const outPath = path.join("./", `${filePath}-story.png`);
|
||||
const extIndex = filePath.lastIndexOf(".");
|
||||
const baseName = extIndex !== -1 ? filePath.substring(0, extIndex) : filePath;
|
||||
const outPath = path.join("./", `${baseName}-story.png`);
|
||||
const buffer = canvas.toBuffer("image/png");
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import ModelClient, { isUnexpected } from "@azure-rest/ai-inference";
|
||||
import { AzureKeyCredential } from "@azure/core-auth";
|
||||
|
||||
const KEY = process.env.NEIS_API_KEY;
|
||||
|
||||
export function removeNutritionInfo(value: string): string {
|
||||
|
|
@ -23,3 +26,55 @@ export async function getMealInfo(MLSV_YMD: string): Promise<{ meal: string; dat
|
|||
|
||||
}
|
||||
|
||||
export async function NameToEmoji(name: string): Promise<string> {
|
||||
const token = process.env.GITHUB_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error("GITHUB_TOKEN environment variable is not set.");
|
||||
}
|
||||
const endpoint = "https://models.github.ai/inference";
|
||||
const model = "openai/gpt-4.1";
|
||||
|
||||
const client = ModelClient(
|
||||
endpoint,
|
||||
new AzureKeyCredential(token),
|
||||
);
|
||||
|
||||
const systemPrompt = `You are an emoji responder.
|
||||
When given any word or phrase, you must reply with exactly one emoji per item, matching the meaning as closely as possible.
|
||||
**If multiple words or phrases are given, they will be separated by commas (,), and your emojis must also be separated by commas (,) in the same order.**
|
||||
Do not include any words, explanations, or multiple emojis—just **one emoji per item**.
|
||||
|
||||
Examples:
|
||||
Q: 현미찹쌀밥
|
||||
A: 🍚
|
||||
Q: 개
|
||||
A: 🐶
|
||||
Q: 축구
|
||||
A: ⚽
|
||||
Q: 해넘이
|
||||
A: 🌇
|
||||
Q: 현미찹쌀밥,개,축구
|
||||
A: 🍚,🐶,⚽
|
||||
`;
|
||||
|
||||
const response = await client.path("/chat/completions").post({
|
||||
body: {
|
||||
messages: [
|
||||
{ role: "system", content: systemPrompt },
|
||||
{ role: "user", content: name }
|
||||
],
|
||||
temperature: 1.0,
|
||||
top_p: 1.0,
|
||||
model: model
|
||||
}
|
||||
});
|
||||
if (isUnexpected(response)) {
|
||||
throw response.body.error;
|
||||
}
|
||||
|
||||
const choices = response.body?.choices;
|
||||
if (!choices || !choices[0]?.message?.content) {
|
||||
throw new Error("No valid response from the model.");
|
||||
}
|
||||
return choices[0].message.content as string;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue