From d47230c98f6fcd6f18bf91f32a0a84722951f242 Mon Sep 17 00:00:00 2001 From: Shuanglei Tao Date: Mon, 26 May 2025 22:59:38 +0800 Subject: [PATCH] update html --- html/css/main.css | 17 ++++++++++++++ html/index.html | 8 +++---- html/js/dithering.js | 55 ++++---------------------------------------- html/js/main.js | 52 +++++++++++++++++++++++------------------ 4 files changed, 56 insertions(+), 76 deletions(-) diff --git a/html/css/main.css b/html/css/main.css index cd7a397..06963ca 100644 --- a/html/css/main.css +++ b/html/css/main.css @@ -413,6 +413,23 @@ body.debug-mode .tool-button.active { border-color: var(--primary-hover); } +input[type=text]:disabled, +input[type=number]:disabled, +select:disabled { + opacity: 0.65; + cursor: not-allowed; + background-color: #e9ecef; + color: #6c757d; +} + +body.debug-mode input[type=text]:disabled, +body.debug-mode input[type=number]:disabled, +body.debug-mode select:disabled { + background-color: #1a1a1a; + color: #666; + border-color: #2a2a2a; +} + @media (max-width: 768px) { .flex-container { flex-direction: column; diff --git a/html/index.html b/html/index.html index b9f4d42..44efe5c 100644 --- a/html/index.html +++ b/html/index.html @@ -48,12 +48,12 @@
蓝牙传图
- +
- @@ -68,7 +68,7 @@
- +
@@ -80,7 +80,7 @@
状态:
- +
diff --git a/html/js/dithering.js b/html/js/dithering.js index 9920712..9f5d78b 100644 --- a/html/js/dithering.js +++ b/html/js/dithering.js @@ -4,11 +4,6 @@ const bwrPalette = [ [255, 0, 0, 255] ] -const bwPalette = [ - [0, 0, 0, 255], - [255, 255, 255, 255], -] - function dithering(ctx, width, height, threshold, type) { const bayerThresholdMap = [ [ 15, 135, 45, 165 ], @@ -26,7 +21,6 @@ function dithering(ctx, width, height, threshold, type) { lumB[i] = i*0.114; } const imageData = ctx.getImageData(0, 0, width, height); - const imageDataLength = imageData.data.length; // Greyscale luminance (sets r pixels to luminance of rgb) @@ -38,21 +32,15 @@ function dithering(ctx, width, height, threshold, type) { let newPixel, err; for (let currentPixel = 0; currentPixel <= imageDataLength; currentPixel+=4) { - if (type === "gray") { - const factor = 255 / (threshold - 1); - imageData.data[currentPixel] = Math.round(imageData.data[currentPixel] / factor) * factor; - } else if (type ==="none") { - // No dithering + if (type ==="none") { // No dithering imageData.data[currentPixel] = imageData.data[currentPixel] < threshold ? 0 : 255; - } else if (type ==="bayer") { - // 4x4 Bayer ordered dithering algorithm + } else if (type ==="bayer") { // 4x4 Bayer ordered dithering algorithm var x = currentPixel/4 % w; var y = Math.floor(currentPixel/4 / w); var map = Math.floor( (imageData.data[currentPixel] + bayerThresholdMap[x%4][y%4]) / 2 ); imageData.data[currentPixel] = (map < threshold) ? 0 : 255; - } else if (type ==="floydsteinberg") { - // Floyda€"Steinberg dithering algorithm - newPixel = imageData.data[currentPixel] < 129 ? 0 : 255; + } else if (type ==="floydsteinberg") { // Floyda€"Steinberg dithering algorithm + newPixel = imageData.data[currentPixel] < threshold ? 0 : 255; err = Math.floor((imageData.data[currentPixel] - newPixel) / 16); imageData.data[currentPixel] = newPixel; @@ -60,8 +48,7 @@ function dithering(ctx, width, height, threshold, type) { imageData.data[currentPixel + 4*w - 4 ] += err*3; imageData.data[currentPixel + 4*w ] += err*5; imageData.data[currentPixel + 4*w + 4 ] += err*1; - } else { - // Bill Atkinson's dithering algorithm + } else { // Bill Atkinson's dithering algorithm newPixel = imageData.data[currentPixel] < threshold ? 0 : 255; err = Math.floor((imageData.data[currentPixel] - newPixel) / 8); imageData.data[currentPixel] = newPixel; @@ -108,36 +95,6 @@ function canvas2bytes(canvas, step = 'bw', invert = false) { return arr; } -function getColorDistance(rgba1, rgba2) { - const [r1, b1, g1] = rgba1; - const [r2, b2, g2] = rgba2; - - const rm = (r1 + r2 ) / 2; - - const r = r1 - r2; - const g = g1 - g2; - const b = b1 - b2; - - return Math.sqrt((2 + rm / 256) * r * r + 4 * g * g + (2 + (255 - rm) / 256) * b * b); -} - -function getNearColor(pixel, palette) { - let minDistance = 255 * 255 * 3 + 1; - let paletteIndex = 0; - - for (let i = 0; i < palette.length; i++) { - const targetColor = palette[i]; - const distance = getColorDistance(pixel, targetColor); - if (distance < minDistance) { - minDistance = distance; - paletteIndex = i; - } - } - - return palette[paletteIndex]; -} - - function getNearColorV2(color, palette) { let minDistanceSquared = 255*255 + 255*255 + 255*255 + 1; @@ -153,10 +110,8 @@ function getNearColorV2(color, palette) { } } return palette[bestIndex]; - } - function updatePixel(imageData, index, color) { imageData[index] = color[0]; imageData[index+1] = color[1]; diff --git a/html/js/main.js b/html/js/main.js index febb795..f6dae68 100644 --- a/html/js/main.js +++ b/html/js/main.js @@ -22,6 +22,24 @@ const EpdCmd = { CFG_ERASE: 0x99, }; +function hex2bytes(hex) { + for (var bytes = [], c = 0; c < hex.length; c += 2) + bytes.push(parseInt(hex.substr(c, 2), 16)); + return new Uint8Array(bytes); +} + +function bytes2hex(data) { + return new Uint8Array(data).reduce( + function (memo, i) { + return memo + ("0" + i.toString(16)).slice(-2); + }, ""); +} + +function intToHex(intIn) { + let stringOut = ("0000" + intIn.toString(16)).substr(-4) + return stringOut.substring(2, 4) + stringOut.substring(0, 2); +} + function resetVariables() { gattServer = null; epdService = null; @@ -324,29 +342,18 @@ function clearLog() { document.getElementById("log").innerHTML = ''; } -function hex2bytes(hex) { - for (var bytes = [], c = 0; c < hex.length; c += 2) - bytes.push(parseInt(hex.substr(c, 2), 16)); - return new Uint8Array(bytes); +function onDitheringChange() { + const mode = document.getElementById('dithering').value; + const thresholdInput = document.getElementById('threshold'); + thresholdInput.disabled = (mode === '' || mode.startsWith('bwr')); + updateImage(false); } -function bytes2hex(data) { - return new Uint8Array(data).reduce( - function (memo, i) { - return memo + ("0" + i.toString(16)).slice(-2); - }, ""); -} - -function intToHex(intIn) { - let stringOut = ("0000" + intIn.toString(16)).substr(-4) - return stringOut.substring(2, 4) + stringOut.substring(0, 2); -} - -async function update_image(clear = false) { +function updateImage(clear = false) { const image_file = document.getElementById('image_file'); if (image_file.files.length == 0) return; - if (clear) clear_canvas(); + if (clear) clearCanvas(); const file = image_file.files[0]; let image = new Image();; @@ -354,11 +361,11 @@ async function update_image(clear = false) { image.onload = function(event) { URL.revokeObjectURL(this.src); ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height); - convert_dithering() + convertDithering() } } -function clear_canvas() { +function clearCanvas() { if (confirm('清除画布已有内容?')) { ctx.fillStyle = 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); @@ -367,14 +374,15 @@ function clear_canvas() { return false; } -function convert_dithering() { +function convertDithering() { const mode = document.getElementById('dithering').value; if (mode === '') return; if (mode.startsWith('bwr')) { ditheringCanvasByPalette(canvas, bwrPalette, mode); } else { - dithering(ctx, canvas.width, canvas.height, parseInt(document.getElementById('threshold').value), mode); + const threshold = document.getElementById('threshold').value; + dithering(ctx, canvas.width, canvas.height, parseInt(threshold), mode); } }