import { readPsd } from 'ag-psd' import sharp from 'sharp' import fs from 'fs/promises' interface PsdProcessResult { success: boolean previewPath?: string width?: number height?: number error?: string } /** * 从PSD文件生成预览图 * @param psdFilePath PSD文件路径 * @param outputPath 输出预览图路径 * @param maxSize 最大尺寸(宽或高),默认800px * @returns 处理结果 */ export async function generatePsdPreview( psdFilePath: string, outputPath: string, maxSize: number = 800 ): Promise { try { // 读取PSD文件 const psdBuffer = await fs.readFile(psdFilePath) // 解析PSD const psd = readPsd(psdBuffer, { skipLayerImageData: true, // 跳过图层数据,只读取合成图像 skipThumbnail: false }) if (!psd) { return { success: false, error: 'Failed to parse PSD file' } } // 获取PSD的宽高 const width = psd.width || 0 const height = psd.height || 0 if (width === 0 || height === 0) { return { success: false, error: 'Invalid PSD dimensions' } } // 如果PSD有缩略图,优先使用缩略图 if (psd.imageData) { const imageData = psd.imageData const channels = 4 // RGBA // 将PSD图像数据转换为Buffer const rawBuffer = Buffer.from(imageData.data) // 使用Sharp处理图像 await sharp(rawBuffer, { raw: { width: imageData.width, height: imageData.height, channels: channels } }) .resize(maxSize, maxSize, { fit: 'inside', withoutEnlargement: true }) .jpeg({ quality: 90, mozjpeg: true }) .toFile(outputPath) return { success: true, previewPath: outputPath, width, height } } return { success: false, error: 'No image data found in PSD file' } } catch (error) { console.error('Error generating PSD preview:', error) return { success: false, error: error instanceof Error ? error.message : 'Unknown error' } } } /** * 检查文件是否为PSD格式 * @param filePath 文件路径 * @returns 是否为PSD文件 */ export async function isPsdFile(filePath: string): Promise { try { const buffer = await fs.readFile(filePath, { encoding: null }) // PSD文件签名:8BPS return buffer.length > 4 && buffer[0] === 0x38 && // '8' buffer[1] === 0x42 && // 'B' buffer[2] === 0x50 && // 'P' buffer[3] === 0x53 // 'S' } catch { return false } } /** * 从文件扩展名判断是否为PSD * @param filename 文件名 * @returns 是否为PSD文件 */ export function hasPsdExtension(filename: string): boolean { return filename.toLowerCase().endsWith('.psd') }