Skip to main content
Glama
logo-optimizer.js4.71 kB
import sharp from 'sharp'; export class LogoOptimizer { async convertToPNG(buffer, targetSize = 256) { try { return await sharp(buffer) .resize(targetSize, targetSize, { fit: 'contain', background: { r: 255, g: 255, b: 255, alpha: 0 } }) .png({ quality: 90, compressionLevel: 6, adaptiveFiltering: true }) .toBuffer(); } catch (error) { throw new Error(`PNG转换失败: ${error}`); } } async optimizeSVG(buffer) { try { let svgContent = buffer.toString('utf-8'); // 基础SVG优化 svgContent = this.cleanSVGContent(svgContent); svgContent = this.optimizeSVGAttributes(svgContent); return Buffer.from(svgContent, 'utf-8'); } catch (error) { throw new Error(`SVG优化失败: ${error}`); } } cleanSVGContent(svgContent) { // 移除注释 svgContent = svgContent.replace(/<!--[\s\S]*?-->/g, ''); // 移除不必要的空白字符 svgContent = svgContent.replace(/\s+/g, ' '); // 移除空的属性 svgContent = svgContent.replace(/\s+[a-zA-Z-]+=""\s*/g, ' '); return svgContent.trim(); } optimizeSVGAttributes(svgContent) { // 确保SVG有正确的viewBox if (!svgContent.includes('viewBox') && svgContent.includes('width') && svgContent.includes('height')) { const widthMatch = svgContent.match(/width="(\d+)"/); const heightMatch = svgContent.match(/height="(\d+)"/); if (widthMatch && heightMatch) { const width = widthMatch[1]; const height = heightMatch[1]; svgContent = svgContent.replace(/<svg([^>]*)>/, `<svg$1 viewBox="0 0 ${width} ${height}">`); } } return svgContent; } async enhanceImage(buffer, format) { try { if (format === 'svg') { return this.optimizeSVG(buffer); } // 对于位图格式,进行基础增强 return await sharp(buffer) .sharpen() .normalize() .toBuffer(); } catch (error) { throw new Error(`图像增强失败: ${error}`); } } async createMultipleFormats(buffer, originalFormat, targetSize = 256) { const results = []; try { // PNG格式 const pngBuffer = await this.convertToPNG(buffer, targetSize); results.push({ format: 'png', buffer: pngBuffer, size: targetSize }); // 如果原始是SVG,保留优化后的SVG if (originalFormat === 'svg') { const optimizedSvg = await this.optimizeSVG(buffer); results.push({ format: 'svg', buffer: optimizedSvg, size: 0 // SVG是矢量格式 }); } // WebP格式(现代浏览器支持) try { const webpBuffer = await sharp(buffer) .resize(targetSize, targetSize, { fit: 'contain', background: { r: 255, g: 255, b: 255, alpha: 0 } }) .webp({ quality: 90 }) .toBuffer(); results.push({ format: 'webp', buffer: webpBuffer, size: targetSize }); } catch { // WebP转换失败时忽略 } return results; } catch (error) { throw new Error(`多格式转换失败: ${error}`); } } async generateFavicons(buffer) { const faviconSizes = [16, 32, 48, 64, 128, 256]; const favicons = []; for (const size of faviconSizes) { try { const faviconBuffer = await sharp(buffer) .resize(size, size, { fit: 'contain', background: { r: 255, g: 255, b: 255, alpha: 0 } }) .png() .toBuffer(); favicons.push({ size, buffer: faviconBuffer }); } catch (error) { console.warn(`生成 ${size}x${size} favicon失败:`, error); } } return favicons; } } //# sourceMappingURL=logo-optimizer.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/xtdexw/logo-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server