Joey / src /utils /file-utils.ts
yuanjiajun
feat: 单图
139dfb9
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<string> => {
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;
}