( ′∀`)σ≡σ☆))Д′)レ(゚∀゚;)ヘ=З=З=Зε≡(ノ´_ゝ`)ノ
const fs = require('fs');
const puppeteer = require('puppeteer');
(async () => {
const filePath = process.argv[2];
const outputPath = process.argv[3];
const format = (process.argv[4] || 'png').toLowerCase();
if (!filePath || !fs.existsSync(filePath)) {
console.error("Missing or invalid SVG file path.");
process.exit(1);
}
if (!outputPath) {
console.error("Missing output file path.");
process.exit(1);
}
if (!['png', 'jpeg', 'pdf'].includes(format)) {
console.error("Invalid format specified. Allowed: png, jpeg, pdf");
process.exit(1);
}
try {
// Detect if input is base64 or raw SVG
const fileContent = fs.readFileSync(filePath, 'utf-8').trim();
const svgContent = fileContent.match(/^<svg[\s\S]*<\/svg>$/i)
? fileContent
: Buffer.from(fileContent, 'base64').toString('utf-8');
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--font-render-hinting=none',
'--enable-font-antialiasing'
],
headless: 'new'
});
const page = await browser.newPage();
// Set viewport for raster formats
if (format === 'png' || format === 'jpeg') {
await page.setViewport({ width: 1125, height: 675 });
}
// Your original font and emoji CSS preserved exactly
const htmlContent = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
@font-face {
font-family: 'EmojiFont';
src: local('Apple Color Emoji'), local('Segoe UI Emoji'), local('Noto Color Emoji');
}
body, svg {
font-family: 'EmojiFont', 'Segoe UI Emoji', 'Noto Color Emoji', 'Apple Color Emoji', 'Segoe UI Symbol', 'Arial', sans-serif;
margin: 0; padding: 0;
background: transparent !important;
}
html, body, svg {
width: 100vw;
height: 100vh;
background: transparent !important;
}
</style>
</head>
<body>
${svgContent}
</body>
</html>
`;
await page.setContent(htmlContent, { waitUntil: 'networkidle0' });
// Wait for fonts to load
await page.evaluate(async () => {
if (document.fonts && document.fonts.status !== 'loaded') {
await document.fonts.ready;
}
// Explicitly ensure body background is transparent for omitBackground to work
document.body.style.background = 'transparent';
});
if (format === 'pdf') {
await page.pdf({
path: outputPath,
printBackground: true,
width: '1125px',
height: '675px',
pageRanges: '1',
});
} else {
// Screenshot the SVG element only
const svgHandle = await page.$('svg');
if (!svgHandle) throw new Error('SVG element not found.');
const boundingBox = await svgHandle.boundingBox();
await page.screenshot({
path: outputPath,
type: format,
omitBackground: format === 'png', // Enable transparency only for PNG
clip: boundingBox || undefined
});
}
await browser.close();
console.log(`✅ ${format.toUpperCase()} created successfully at ${outputPath}`);
} catch (error) {
console.error("❌ Error during conversion:", error);
process.exit(1);
}
})();