1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
| import sharp from "sharp"; import { createCanvas, registerFont, loadImage } from "canvas"; import path from "path"; import { fileURLToPath } from "url";
const bgPath = "background.jpg"; const fontPath = "SourceHanSansJP-Bold.otf"; const outPath = "C:\\cover"; const fontSize = 128;
function isHalfWidth(ch) { return /^[\x00-\x7F]$/.test(ch); }
function drawTextLine(ctx, text, xCenter, y, fontSize) { let x = xCenter - ctx.measureText(text).width / 2;
for (const ch of text) { const w = ctx.measureText(ch).width;
ctx.fillText(ch, x + w / 2, y);
x += w; } }
function splitTextWithNewline(ctx, text, maxWidth) { const rawLines = text.split("\\n"); const result = [];
rawLines.forEach(segment => { const wrappedLines = wrapText(ctx, segment, maxWidth); result.push(...wrappedLines); });
return result; }
function wrapText(ctx, text, maxWidth) { const lines = []; let line = "";
for (const char of text) { const testLine = line + char; const { width: testWidth } = ctx.measureText(testLine);
if (testWidth > maxWidth && line !== "") { lines.push(line); line = char; } else { line = testLine; } } if (line) lines.push(line);
return lines; }
async function drawTextOnImage(backgroundFile, text, ouputPath,filename, fontFile) { const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename);
const backgroundPath = path.join(__dirname, backgroundFile);
const image = sharp(backgroundPath); const { width, height } = await image.metadata();
const fontPath = path.join(__dirname, fontFile); registerFont(fontPath, { family: "SHSJP" });
const canvas = createCanvas(width, height); const ctx = canvas.getContext("2d");
const bgImage = await loadImage(backgroundPath); ctx.drawImage(bgImage, 0, 0, width, height);
ctx.font = `${fontSize}px 'SHSJP'`; ctx.fillStyle = "black"; ctx.textAlign = "center"; ctx.textBaseline = "middle";
const maxTextWidth = width * 0.9; const lines = splitTextWithNewline(ctx, text, maxTextWidth);
const lineHeight = fontSize * 1.2; const totalHeight = lines.length * lineHeight; const startY = height / 2 - totalHeight / 2 + lineHeight / 2;
lines.forEach((line, i) => { const y = startY + i * lineHeight; drawTextLine(ctx, line, width / 2, y, fontSize); });
const outputImagePath = path.join(ouputPath, filename + ".jpg");
const outBuffer = canvas.toBuffer("image/png"); await sharp(outBuffer) .jpeg({ quality: 90 }) .toFile(outputImagePath);
console.log("出力完了:", outputImagePath); }
const [, , filename, text] = process.argv;
if (!filename || !text) { console.log("使い方: node image_text.js <出力ファイル名> <テキスト>"); process.exit(1); }
drawTextOnImage(bgPath, text, outPath,filename, fontPath);
|