☰
Python上传图片后自动将其处理成像素方块风格
2026/10/2 12:49:39 网站建设 项目流程

这是一个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" 控制,您可按需修改。

文章仅供参考学习用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询