document.addEventListener('DOMContentLoaded', () => { const imageUpload = document.getElementById('image-upload'); const blockSizeInput = document.getElementById('block-size'); const blockValueDisplay = document.getElementById('block-value'); const originalCanvas = document.getElementById('original-canvas'); const mosaicCanvas = document.getElementById('mosaic-canvas'); const downloadBtn = document.getElementById('download-btn'); const ctxOriginal = originalCanvas.getContext('2d'); const ctxMosaic = mosaicCanvas.getContext('2d'); let currentImage = null; let blockSize = parseInt(blockSizeInput.value);
// 更新块大小显示 blockSizeInput.addEventListener('input', () => { blockSize = parseInt(blockSizeInput.value); blockValueDisplay.textContent = blockSize; if (currentImage) { applyMosaicEffect(currentImage); } });
// 图片上传处理 imageUpload.addEventListener('change', (e) => { const file = e.target.files[0]; if (!file) return;
const reader = new FileReader(); reader.onload = (event) => { const img = new Image(); img.onload = () => { currentImage = img; displayOriginalImage(img); applyMosaicEffect(img); downloadBtn.disabled = false; }; img.src = event.target.result; }; reader.readAsDataURL(file); });
// 显示原图 function displayOriginalImage(img) { // 设置画布尺寸 const maxWidth = originalCanvas.parentElement.clientWidth - 40; const maxHeight = originalCanvas.parentElement.clientHeight - 60; const ratio = Math.min(maxWidth / img.width, maxHeight / img.height); originalCanvas.width = img.width * ratio; originalCanvas.height = img.height * ratio; mosaicCanvas.width = originalCanvas.width; mosaicCanvas.height = originalCanvas.height; // 绘制原图 ctxOriginal.clearRect(0, 0, originalCanvas.width, originalCanvas.height); ctxOriginal.drawImage(img, 0, 0, originalCanvas.width, originalCanvas.height); }
// 应用马赛克效果 function applyMosaicEffect(img) { // 复制原图画布到马赛克画布 ctxMosaic.clearRect(0, 0, mosaicCanvas.width, mosaicCanvas.height); ctxMosaic.drawImage(originalCanvas, 0, 0); // 获取图像数据 const imageData = ctxMosaic.getImageData(0, 0, mosaicCanvas.width, mosaicCanvas.height); const data = imageData.data; // 应用马赛克效果 for (let y = 0; y < mosaicCanvas.height; y += blockSize) { for (let x = 0; x < mosaicCanvas.width; x += blockSize) { // 计算当前块的边界 const blockWidth = Math.min(blockSize, mosaicCanvas.width - x); const blockHeight = Math.min(blockSize, mosaicCanvas.height - y); // 计算块内平均颜色 const avgColor = getAverageColor(data, x, y, blockWidth, blockHeight, mosaicCanvas.width); // 填充块 ctxMosaic.fillStyle = `rgb(${avgColor.r}, ${avgColor.g}, ${avgColor.b})`; ctxMosaic.fillRect(x, y, blockWidth, blockHeight); } } }
// 计算块内平均颜色 function getAverageColor(data, x, y, width, height, canvasWidth) { let r = 0, g = 0, b = 0, count = 0; for (let i = 0; i < height; i++) { for (let j = 0; j < width; j++) { const pxX = x + j; const pxY = y + i; const index = (pxY * canvasWidth + pxX) * 4; r += data[index]; g += data[index + 1]; b += data[index + 2]; count++; } } return { r: Math.round(r / count), g: Math.round(g / count), b: Math.round(b / count) }; }
// 下载功能 downloadBtn.addEventListener('click', () => { if (!currentImage) return; const link = document.createElement('a'); link.download = 'mosaic-image.png'; link.href = mosaicCanvas.toDataURL('image/png'); link.click(); });});
评论