import axios from 'axios'; import fs from 'fs'; import os from 'os'; import path from 'path'; import sharp from 'sharp'; import { getRandomUniqueElements } from './common'; import { requestQwImage } from './hugging-face'; import { emotionalStoryCover } from '@/const'; // 创建上传文件夹,如果不存在 export const createUploadDir = (): string => { const uploadDir = path.join(__dirname, '../../uploads'); if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir); } return uploadDir; }; // 使用 sharp 将 Buffer 转换为 JPG 并保存到本地文件系统 export const bufferToJpg = async (data: Buffer, outputFilename: string, uploadDir: string): Promise => { const outputPath = path.join(uploadDir, outputFilename); await sharp(data).toFormat('jpg').toFile(outputPath); return outputFilename; }; // 检查文件是否存在并返回文件流(如果存在) export const getFileStream = (filename: string, uploadDir: string) => { const filePath = path.join(uploadDir, filename); if (fs.existsSync(filePath)) { return fs.createReadStream(filePath); } return null; }; export function bufferToBase64ImageSrc(buffer: Buffer, mimeType: string): string { // 将 Buffer 转换为 base64 字符串 const base64 = buffer.toString('base64'); // 构建 base64 图片源 return `data:${mimeType};base64,${base64}`; } export async function downloadDocx(url: string, fileName: string) { try { // 发起 GET 请求下载文件 const response = await axios.get(url, { responseType: 'arraybuffer', // 设置响应类型为 blob }); // 确保响应头中的 Content-Type 为 DOCX 文件 const contentType = response.headers['content-type']; if (contentType !== 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') { throw new Error(`Unexpected content type: ${contentType}`); } const arrayBuffer = response.data as ArrayBuffer; const buffer = Buffer.from(arrayBuffer); // 获取用户的桌面路径 const desktopPath = path.join(os.homedir(), 'Desktop'); if (!fs.existsSync(desktopPath)) { throw new Error('Desktop path does not exist. Please ensure you have a Desktop directory.'); } const filePath = path.join(desktopPath, fileName); // 将 Buffer 写入到文件 fs.writeFileSync(filePath, buffer); } catch (error) { console.error('下载文件时出错:', error); } } export async function getFluxImageBuffer(text: string, apiKey: string) { try { const response = await axios.post( 'https://api-inference.huggingface.co/models/black-forest-labs/FLUX.1-dev', { inputs: text, options: { use_cache: true, }, }, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}`, }, responseType: 'arraybuffer', // 设置响应类型为 blob }, ); const arrayBuffer = response.data as ArrayBuffer; return Buffer.from(arrayBuffer); } catch (error) { throw new Error(`生成图片失败,错误信息:${error}`); } } export async function blobToArrayBuffer(blobOrArrayBuffer: Blob | ArrayBuffer){ try { return await (blobOrArrayBuffer as Blob).arrayBuffer() } catch (error) { return blobOrArrayBuffer } } export async function getImageBase64ByText(text: string, hfApiKey: string) { console.log(`------------ 开始获取图片,原文案:${text} ---------------`); // const summary = await requestQw({ // messages: [ // { // role: 'user', // content: `翻译成英语并简化内容提炼核心,控制在十五个单词内:${text}`, // }, // ], // model: 'qwen-plus', // }); // console.log(`summary:${summary}`); // const buffer = await getFluxImageBuffer(`modern China:${summary}`, hfApiKey); // const imageBase64 = bufferToBase64ImageSrc(buffer, 'image/png'); const coverTheme = getRandomUniqueElements(emotionalStoryCover, 1)[0]; const base64 = await requestQwImage({ prompt: `手机拍摄,贴近现实生活,灰土气息,纯风景,不要人物和动物:${coverTheme}`, model: 'qwen-plus', response_format: 'b64_json', }); const imageBase64 = `data:image/png;base64,${base64}`; console.log('------------- 图片Base64获取成功 ---------------'); return imageBase64; }