ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python上传图片后自动将其处理成像素方块风格

Python上传图片后自动将其处理成像素方块风格 这是一个HTML代码上传图片后自动将其处理成像素方块风格并支持调整方块大小和下载结果。html!DOCTYPE htmlhtml langzh-CNheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title图片像素方块化/titlestyle* { 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[typerange] { 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/headbodydiv classpanellabel classfile-btn选择图片input typefile idfile acceptimage/*/labellabel方块大小input typerange idsize min2 max64 value12span classvalue idsizeVal12/span/labelbutton iddownload disabled下载 PNG/button/divdiv idstagep classhint点击「选择图片」或把图片拖到这里 / 直接 CtrlV 粘贴/p/divscript/* 元素引用 */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[i1]},${smallData[i2]},${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像素方块化工具的功能拆解· 图片上传入口页面提供“选择图片”按钮同时支持拖拽图片到虚线区域或直接使用 CtrlV 粘贴图片。· 方块大小调节通过滑块控制每个像素方块的边长2~64像素拖动时右侧数值会同步变化并即时重新渲染预览。· 像素化渲染逻辑先算出原图会被切成多少行、多少列再将原图高质量缩小到对应的小尺寸最后逐个方块填充纯色保证边缘硬朗清晰。· 结果导出点击“下载 PNG”按钮会将当前画布内容保存为 pixel-xxpx.png方便直接使用。---优化建议 若想改变默认方块大小可调整滑块初始值当前为12最大、最小值由 min2 和 max64 控制您可按需修改。文章仅供参考学习用。
返回列表