这是一个HTML代码,上传图片后自动将其处理成像素方块风格,并支持调整方块大小和下载结果。
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片像素方块化</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0; min-height: 100vh; padding: 24px;
font-family: system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
background: #14161a; color: #e8eaed;
display: flex; flex-direction: column; align-items: center; gap: 18px;
}
.panel {
display: flex; flex-wrap: wrap; gap: 16px; align-items: center; justify-content: center;
background: #1e2128; padding: 14px 18px; border-radius: 14px;
box-shadow: 0 6px 24px rgba(0,0,0,.35);
}
label { display: flex; align-items: center; gap: 8px; font-size: 14px; }
input[type="range"] { width: 160px; accent-color: #4f9cff; }
button, .file-btn {
border: none; border-radius: 9px; padding: 9px 16px; font-size: 14px;
background: #4f9cff; color: #fff; cursor: pointer; transition: .2s;
}
button:hover, .file-btn:hover { background: #3a86e8; }
button:disabled { opacity: .4; cursor: not-allowed; }
#file { display: none; }
#stage {
max-width: 100%; display: flex; align-items: center; justify-content: center;
border: 2px dashed #333842; border-radius: 16px; padding: 16px; min-height: 220px;
width: min(1000px, 100%);
}
#stage.dragover { border-color: #4f9cff; background: rgba(79,156,255,.08); }
canvas { max-width: 100%; height: auto; display: block; image-rendering: pixelated; }
.hint { color: #7c8493; font-size: 13px; }
.value { width: 34px; text-align: right; color: #4f9cff; font-variant-numeric: tabular-nums; }
</style>
</head>
<body>
<div class="panel">
<label class="file-btn">
选择图片
<input type="file" id="file" accept="image/*">
</label>
<label>
方块大小
<input type="range" id="size" min="2" max="64" value="12">
<span class="value" id="sizeVal">12</span>
</label>
<button id="download" disabled>下载 PNG</button>
</div>
<div id="stage">
<p class="hint">点击「选择图片」,或把图片拖到这里 / 直接 Ctrl+V 粘贴</p>
</div>
<script>
/* ========== 元素引用 ========== */
const fileInput = document.getElementById('file');
const sizeInput = document.getElementById('size');
const sizeVal = document.getElementById('sizeVal');
const stage = document.getElementById('stage');
const downloadBtn= document.getElementById('download');
let canvas = null; // 输出画布
let ctx = null;
let sourceImg = null; // 原始图片对象
/* ========== 读取文件 ========== */
function loadFile(file) {
if (!file || !file.type.startsWith('image/')) return;
const url = URL.createObjectURL(file);
const img = new Image();
img.onload = () => {
sourceImg = img;
URL.revokeObjectURL(url);
render();
downloadBtn.disabled = false;
};
img.onerror = () => alert('图片读取失败,请换一张试试');
img.src = url;
}
/* ========== 高质量缩小(逐级减半,保证取到准确的平均色) ========== */
function downscale(src, srcW, srcH, dstW, dstH) {
// 先把原图画到临时画布
let cur = document.createElement('canvas');
cur.width = srcW; cur.height = srcH;
cur.getContext('2d').drawImage(src, 0, 0);
let cw = srcW, ch = srcH;
// 每次缩小一半,直到接近目标尺寸,避免一次性大幅缩放产生锯齿/偏色
while (cw / 2 >= dstW && ch / 2 >= dstH && cw > 2 && ch > 2) {
const nw = Math.max(1, Math.floor(cw / 2));
const nh = Math.max(1, Math.floor(ch / 2));
const next = document.createElement('canvas');
next.width = nw; next.height = nh;
const nctx = next.getContext('2d');
nctx.imageSmoothingEnabled = true;
nctx.imageSmoothingQuality = 'high';
nctx.drawImage(cur, 0, 0, cw, ch, 0, 0, nw, nh);
cur = next; cw = nw; ch = nh;
}
// 最后一步缩到目标尺寸
const out = document.createElement('canvas');
out.width = dstW; out.height = dstH;
const octx = out.getContext('2d');
octx.imageSmoothingEnabled = true;
octx.imageSmoothingQuality = 'high';
octx.drawImage(cur, 0, 0, cw, ch, 0, 0, dstW, dstH);
return out;
}
/* ========== 核心:渲染像素方块图 ========== */
function render() {
if (!sourceImg) return;
const block = Number(sizeInput.value); // 每个方块边长(像素)
const W = sourceImg.naturalWidth;
const H = sourceImg.naturalHeight;
// 1. 计算缩略图尺寸:原图被切成多少个小格子
const cols = Math.max(1, Math.round(W / block));
const rows = Math.max(1, Math.round(H / block));
// 2. 缩小成 cols × rows 的小图,每个像素 = 一个方块的平均色
const small = downscale(sourceImg, W, H, cols, rows);
const smallData = small.getContext('2d').getImageData(0, 0, cols, rows).data;
// 3. 准备输出画布
if (!canvas) {
canvas = document.createElement('canvas');
ctx = canvas.getContext('2d');
stage.innerHTML = '';
stage.appendChild(canvas);
}
const outW = cols * block;
const outH = rows * block;
canvas.width = outW;
canvas.height = outH;
ctx.imageSmoothingEnabled = false; // 关掉平滑,保证方块边缘硬朗
ctx.clearRect(0, 0, outW, outH);
// 4. 逐格铺纯色方块(比直接放大更锐利,不会有插值杂色)
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
const i = (y * cols + x) * 4;
const a = smallData[i + 3];
if (a === 0) continue; // 全透明格子跳过
ctx.fillStyle = `rgba(${smallData[i]},${smallData[i+1]},${smallData[i+2]},${a / 255})`;
ctx.fillRect(x * block, y * block, block, block);
}
}
}
/* ========== 交互事件 ========== */
fileInput.addEventListener('change', e => loadFile(e.target.files[0]));
sizeInput.addEventListener('input', () => {
sizeVal.textContent = sizeInput.value;
render();
});
downloadBtn.addEventListener('click', () => {
if (!canvas) return;
const a = document.createElement('a');
a.download = `pixel-${sizeInput.value}px.png`;
a.href = canvas.toDataURL('image/png');
a.click();
});
/* 拖拽上传 */
['dragenter', 'dragover'].forEach(ev =>
stage.addEventListener(ev, e => { e.preventDefault(); stage.classList.add('dragover'); })
);
['dragleave', 'drop'].forEach(ev =>
stage.addEventListener(ev, e => { e.preventDefault(); stage.classList.remove('dragover'); })
);
stage.addEventListener('drop', e => loadFile(e.dataTransfer.files[0]));
/* 粘贴上传 */
document.addEventListener('paste', e => {
const item = […(e.clipboardData?.items || [])].find(i => i.type.startsWith('image/'));
if (item) loadFile(item.getAsFile());
});
</script>
</body>
</html>
```
像素方块化工具的功能拆解
· 图片上传入口:页面提供“选择图片”按钮,同时支持拖拽图片到虚线区域,或直接使用 Ctrl+V 粘贴图片。
· 方块大小调节:通过滑块控制每个像素方块的边长(2~64像素),拖动时右侧数值会同步变化,并即时重新渲染预览。
· 像素化渲染逻辑:先算出原图会被切成多少行、多少列,再将原图高质量缩小到对应的小尺寸,最后逐个方块填充纯色,保证边缘硬朗清晰。
· 结果导出:点击“下载 PNG”按钮,会将当前画布内容保存为 pixel-xxpx.png,方便直接使用。
—
优化建议: 若想改变默认方块大小,可调整滑块初始值(当前为12);最大、最小值由 min="2" 和 max="64" 控制,您可按需修改。
文章仅供参考学习用。
网硕互联帮助中心




评论前必须登录!
注册