const fs = require('fs'); const path = require('path'); const { createCanvas, loadImage } = require('canvas'); // 配置 const CONFIG = { pixelSize: 100, // 马赛克块大小 inputImage: path.join(__dirname, '参考图.png'), outputMosaic: path.join(__dirname, 'mosaic.png'), outputReport: path.join(__dirname, 'report.html') }; // 主函数 async function main() { try { console.log('开始处理图片...'); // 读取原始图片 const image = await loadImage(CONFIG.inputImage); const width = image.width; const height = image.height; // 创建马赛克图片 console.log('创建马赛克图片...'); const { mosaicCanvas, colorData } = createMosaic(image, width, height, CONFIG.pixelSize); // 保存马赛克图片 const mosaicBuffer = mosaicCanvas.toBuffer('image/png'); fs.writeFileSync(CONFIG.outputMosaic, mosaicBuffer); // 生成报告 console.log('生成HTML报告...'); generateReport(colorData); console.log('处理完成! 报告已生成: ' + CONFIG.outputReport); } catch (error) { console.error('处理过程中出错:', error); } } // 创建马赛克图片并提取颜色 function createMosaic(image, width, height, pixelSize) { // 创建画布 const canvas = createCanvas(width, height); const ctx = canvas.getContext('2d'); // 绘制原始图片 ctx.drawImage(image, 0, 0, width, height); // 颜色映射: 颜色值 -> 出现次数 const colorMap = new Map(); // 遍历图像,按块处理 for (let y = 0; y < height; y += pixelSize) { for (let x = 0; x < width; x += pixelSize) { // 计算当前块的大小 const blockWidth = Math.min(pixelSize, width - x); const blockHeight = Math.min(pixelSize, height - y); // 获取块的像素数据 const imageData = ctx.getImageData(x, y, blockWidth, blockHeight); const data = imageData.data; // 计算平均颜色 let r = 0, g = 0, b = 0; const pixelCount = blockWidth * blockHeight; for (let i = 0; i < data.length; i += 4) { r += data[i]; g += data[i + 1]; b += data[i + 2]; } r = Math.floor(r / pixelCount); g = Math.floor(g / pixelCount); b = Math.floor(b / pixelCount); // 创建颜色键 const colorKey = `rgb(${r},${g},${b})`; // 更新颜色映射 if (colorMap.has(colorKey)) { colorMap.set(colorKey, colorMap.get(colorKey) + 1); } else { colorMap.set(colorKey, 1); } // 填充块 ctx.fillStyle = colorKey; ctx.fillRect(x, y, blockWidth, blockHeight); } } // 转换为数组并排序 const sortedColors = Array.from(colorMap.entries()) .map(([color, count]) => ({ color, count })) .sort((a, b) => b.count - a.count); return { mosaicCanvas: canvas, colorData: sortedColors }; } // 生成HTML报告 function generateReport(colorData) { // 创建HTML内容 const htmlContent = `
从马赛克图中提取的主要颜色(按出现频率排序):