mirror of
https://github.com/jam422470459/EPD-nRF52-hema213.git
synced 2025-12-08 09:28:13 +08:00
add canvas size options
This commit is contained in:
@@ -3,13 +3,13 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>4.2 寸电子墨水屏蓝牙控制器</title>
|
<title>电子墨水屏蓝牙控制器</title>
|
||||||
<link rel="stylesheet" href="css/main.css?v=20250519">
|
<link rel="stylesheet" href="css/main.css?v=20250519">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<h3>4.2 寸电子墨水屏蓝牙控制器</h3>
|
<h3>电子墨水屏蓝牙控制器</h3>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>蓝牙连接</legend>
|
<legend>蓝牙连接</legend>
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
@@ -20,12 +20,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex-group debug">
|
<div class="flex-group debug">
|
||||||
<label for="epddriver">驱动</label>
|
<label for="epddriver">驱动</label>
|
||||||
<select id="epddriver" onchange="updateDitherMode()">
|
<select id="epddriver" onchange="updateDitcherOptions()">
|
||||||
<option value="01" data-color="blackWhiteColor">UC8176/UC8276(黑白)</option>
|
<option value="01" data-color="blackWhiteColor" data-size="4.2_400_300">UC8176/UC8276(黑白)</option>
|
||||||
<option value="03" data-color="threeColor">UC8176/UC8276(三色)</option>
|
<option value="03" data-color="threeColor" data-size="4.2_400_300">UC8176/UC8276(三色)</option>
|
||||||
<option value="04" data-color="blackWhiteColor">SSD1619/SSD1683(黑白)</option>
|
<option value="04" data-color="blackWhiteColor" data-size="4.2_400_300">SSD1619/SSD1683(黑白)</option>
|
||||||
<option value="02" data-color="threeColor">SSD1619/SSD1683(三色)</option>
|
<option value="02" data-color="threeColor" data-size="4.2_400_300">SSD1619/SSD1683(三色)</option>
|
||||||
<option value="05" data-color="fourColor">JD79668(四色)</option>
|
<option value="05" data-color="fourColor" data-size="4.2_400_300">JD79668(四色)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-group debug">
|
<div class="flex-group debug">
|
||||||
@@ -51,6 +51,30 @@
|
|||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<input type="file" id="image_file" onchange="updateImage(true)" accept=".png,.jpg,.bmp,.webp,.jpeg">
|
<input type="file" id="image_file" onchange="updateImage(true)" accept=".png,.jpg,.bmp,.webp,.jpeg">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex-container">
|
||||||
|
<div class="flex-group debug">
|
||||||
|
<label for="canvasSize">画布尺寸:</label>
|
||||||
|
<select id="canvasSize" onchange="updateCanvasSize()">
|
||||||
|
<option value="1.54_152_152">1.54_152_152 (152x152)</option>
|
||||||
|
<option value="1.54_200_200">1.54_200_200 (200x200)</option>
|
||||||
|
<option value="2.13_250_122">2.13_250_122 (250x122)</option>
|
||||||
|
<option value="2.66_296_152">2.66_296_152 (296x152)</option>
|
||||||
|
<option value="2.9_296_128">2.9_296_128 (296x128)</option>
|
||||||
|
<option value="2.9_384_168">2.9_384_168 (384x168)</option>
|
||||||
|
<option value="3.5_384_184">3.5_384_184 (384x184)</option>
|
||||||
|
<option value="3.7_416_240">3.7_416_240 (416x240)</option>
|
||||||
|
<option value="3.97_800_480">3.97_800_480 (800x480)</option>
|
||||||
|
<option value="4.2_400_300" selected>4.2_400_300 (400x300)</option>
|
||||||
|
<option value="5.79_792_272">5.79_792_272 (792x272)</option>
|
||||||
|
<option value="7.5_800_480">7.5_800_480 (800x480)</option>
|
||||||
|
<option value="10.2_960_640">10.2_960_640 (960x640)</option>
|
||||||
|
<option value="10.85_1360_480">10.85_1360_480 (1360x480)</option>
|
||||||
|
<option value="11.6_960_640">11.6_960_640 (960x640)</option>
|
||||||
|
<option value="4E_600_400">4E_600_400 (600x400)</option>
|
||||||
|
<option value="7.3E6">7.3E6 (480x800)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="flex-container options">
|
<div class="flex-container options">
|
||||||
<div class="flex-group debug">
|
<div class="flex-group debug">
|
||||||
<label for="ditherMode">颜色模式:</label>
|
<label for="ditherMode">颜色模式:</label>
|
||||||
|
|||||||
@@ -22,6 +22,26 @@ const EpdCmd = {
|
|||||||
CFG_ERASE: 0x99,
|
CFG_ERASE: 0x99,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const canvasSizes = [
|
||||||
|
{ name: '1.54_152_152', width: 152, height: 152 },
|
||||||
|
{ name: '1.54_200_200', width: 200, height: 200 },
|
||||||
|
{ name: '2.13_250_122', width: 250, height: 122 },
|
||||||
|
{ name: '2.66_296_152', width: 296, height: 152 },
|
||||||
|
{ name: '2.9_296_128', width: 296, height: 128 },
|
||||||
|
{ name: '2.9_384_168', width: 384, height: 168 },
|
||||||
|
{ name: '3.5_384_184', width: 384, height: 184 },
|
||||||
|
{ name: '3.7_416_240', width: 416, height: 240 },
|
||||||
|
{ name: '3.97_800_480', width: 800, height: 480 },
|
||||||
|
{ name: '4.2_400_300', width: 400, height: 300 },
|
||||||
|
{ name: '5.79_792_272', width: 792, height: 272 },
|
||||||
|
{ name: '7.5_800_480', width: 800, height: 480 },
|
||||||
|
{ name: '10.2_960_640', width: 960, height: 640 },
|
||||||
|
{ name: '10.85_1360_480', width: 1360, height: 480 },
|
||||||
|
{ name: '11.6_960_640', width: 960, height: 640 },
|
||||||
|
{ name: '4E_600_400', width: 600, height: 400 },
|
||||||
|
{ name: '7.3E6', width: 480, height: 800 }
|
||||||
|
];
|
||||||
|
|
||||||
function hex2bytes(hex) {
|
function hex2bytes(hex) {
|
||||||
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
||||||
bytes.push(parseInt(hex.substr(c, 2), 16));
|
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||||
@@ -159,9 +179,15 @@ async function sendcmd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function sendimg() {
|
async function sendimg() {
|
||||||
|
const canvasSize = document.getElementById('canvasSize').value;
|
||||||
const ditherMode = document.getElementById('ditherMode').value;
|
const ditherMode = document.getElementById('ditherMode').value;
|
||||||
const epdDriverSelect = document.getElementById('epddriver');
|
const epdDriverSelect = document.getElementById('epddriver');
|
||||||
const selectedOption = epdDriverSelect.options[epdDriverSelect.selectedIndex];
|
const selectedOption = epdDriverSelect.options[epdDriverSelect.selectedIndex];
|
||||||
|
|
||||||
|
if (selectedOption.getAttribute('data-size') !== canvasSize) {
|
||||||
|
addLog(`画布尺寸和驱动不匹配,请重新选择。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (selectedOption.getAttribute('data-color') !== ditherMode) {
|
if (selectedOption.getAttribute('data-color') !== ditherMode) {
|
||||||
addLog(`颜色模式和驱动不匹配,请重新选择。`);
|
addLog(`颜色模式和驱动不匹配,请重新选择。`);
|
||||||
return;
|
return;
|
||||||
@@ -220,27 +246,23 @@ function downloadDataArray() {
|
|||||||
const processedData = processImageData(imageData);
|
const processedData = processImageData(imageData);
|
||||||
const mode = document.getElementById('ditherMode').value;
|
const mode = document.getElementById('ditherMode').value;
|
||||||
|
|
||||||
// 验证六色模式的预期大小
|
|
||||||
if (mode === 'sixColor' && processedData.length !== canvas.width * canvas.height) {
|
if (mode === 'sixColor' && processedData.length !== canvas.width * canvas.height) {
|
||||||
console.log(`错误:预期${canvas.width * canvas.height}字节,但得到${processedData.length}字节`);
|
console.log(`错误:预期${canvas.width * canvas.height}字节,但得到${processedData.length}字节`);
|
||||||
addLog('数组大小不匹配。请检查图像尺寸和模式。');
|
addLog('数组大小不匹配。请检查图像尺寸和模式。');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用数组构建内容,避免拼接问题
|
|
||||||
const dataLines = [];
|
const dataLines = [];
|
||||||
for (let i = 0; i < processedData.length; i++) {
|
for (let i = 0; i < processedData.length; i++) {
|
||||||
const hexValue = (processedData[i] & 0xff).toString(16).padStart(2, '0');
|
const hexValue = (processedData[i] & 0xff).toString(16).padStart(2, '0');
|
||||||
dataLines.push(`0x${hexValue}`);
|
dataLines.push(`0x${hexValue}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 每行格式化16个值
|
|
||||||
const formattedData = [];
|
const formattedData = [];
|
||||||
for (let i = 0; i < dataLines.length; i += 16) {
|
for (let i = 0; i < dataLines.length; i += 16) {
|
||||||
formattedData.push(dataLines.slice(i, i + 16).join(', '));
|
formattedData.push(dataLines.slice(i, i + 16).join(', '));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建最终内容
|
|
||||||
const colorModeValue = mode === 'sixColor' ? 0 : mode === 'fourColor' ? 1 : mode === 'blackWhiteColor' ? 2 : 3;
|
const colorModeValue = mode === 'sixColor' ? 0 : mode === 'fourColor' ? 1 : mode === 'blackWhiteColor' ? 2 : 3;
|
||||||
const arrayContent = [
|
const arrayContent = [
|
||||||
'const uint8_t imageData[] PROGMEM = {',
|
'const uint8_t imageData[] PROGMEM = {',
|
||||||
@@ -253,7 +275,7 @@ function downloadDataArray() {
|
|||||||
|
|
||||||
const blob = new Blob([arrayContent], { type: 'text/plain' });
|
const blob = new Blob([arrayContent], { type: 'text/plain' });
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.download = '图像数据.h';
|
link.download = 'imagedata.h';
|
||||||
link.href = URL.createObjectURL(blob);
|
link.href = URL.createObjectURL(blob);
|
||||||
link.click();
|
link.click();
|
||||||
URL.revokeObjectURL(link.href);
|
URL.revokeObjectURL(link.href);
|
||||||
@@ -323,7 +345,7 @@ function handleNotify(value, idx) {
|
|||||||
epdpins.value = bytes2hex(data.slice(0, 7));
|
epdpins.value = bytes2hex(data.slice(0, 7));
|
||||||
if (data.length > 10) epdpins.value += bytes2hex(data.slice(10, 11));
|
if (data.length > 10) epdpins.value += bytes2hex(data.slice(10, 11));
|
||||||
epddriver.value = bytes2hex(data.slice(7, 8));
|
epddriver.value = bytes2hex(data.slice(7, 8));
|
||||||
updateDitherMode();
|
updateDitcherOptions();
|
||||||
} else {
|
} else {
|
||||||
if (textDecoder == null) textDecoder = new TextDecoder();
|
if (textDecoder == null) textDecoder = new TextDecoder();
|
||||||
addLog(textDecoder.decode(data), '⇓');
|
addLog(textDecoder.decode(data), '⇓');
|
||||||
@@ -411,15 +433,26 @@ function clearLog() {
|
|||||||
document.getElementById("log").innerHTML = '';
|
document.getElementById("log").innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDitherMode() {
|
function updateCanvasSize() {
|
||||||
|
const selectedSizeName = document.getElementById('canvasSize').value;
|
||||||
|
const selectedSize = canvasSizes.find(size => size.name === selectedSizeName);
|
||||||
|
|
||||||
|
canvas.width = selectedSize.width;
|
||||||
|
canvas.height = selectedSize.height;
|
||||||
|
|
||||||
|
updateImage(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDitcherOptions() {
|
||||||
const epdDriverSelect = document.getElementById('epddriver');
|
const epdDriverSelect = document.getElementById('epddriver');
|
||||||
const selectedOption = epdDriverSelect.options[epdDriverSelect.selectedIndex];
|
const selectedOption = epdDriverSelect.options[epdDriverSelect.selectedIndex];
|
||||||
const colorMode = selectedOption.getAttribute('data-color');
|
const colorMode = selectedOption.getAttribute('data-color');
|
||||||
|
const canvasSize = selectedOption.getAttribute('data-size');
|
||||||
|
|
||||||
if (colorMode) {
|
if (colorMode) document.getElementById('ditherMode').value = colorMode;
|
||||||
document.getElementById('ditherMode').value = colorMode;
|
if (canvasSize) document.getElementById('canvasSize').value = canvasSize;
|
||||||
updateImage(false);
|
|
||||||
}
|
updateCanvasSize(); // always update image
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateImage(clear = false) {
|
function updateImage(clear = false) {
|
||||||
|
|||||||
Reference in New Issue
Block a user