update html

This commit is contained in:
Shuanglei Tao
2024-12-25 14:42:48 +08:00
parent 023331b4e1
commit 60d48ad8c4
4 changed files with 244 additions and 374 deletions

View File

@@ -1,160 +0,0 @@
#include "EPD_Test.h"
#include "EPD_4in2.h"
const unsigned char EPD_4IN2_4Gray_lut_vcom[] =
{
0x00 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x60 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x00 ,0x14 ,0x00 ,0x00 ,0x00 ,0x01,
0x00 ,0x13 ,0x0A ,0x01 ,0x00 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
};
const unsigned char EPD_4IN2_4Gray_lut_ww[] ={
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x10 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
0xA0 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
};
const unsigned char EPD_4IN2_4Gray_lut_bw[] ={
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
0x99 ,0x0C ,0x01 ,0x03 ,0x04 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
};
const unsigned char EPD_4IN2_4Gray_lut_wb[] ={
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
0x99 ,0x0B ,0x04 ,0x04 ,0x01 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
};
const unsigned char EPD_4IN2_4Gray_lut_bb[] ={
0x80 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
0x20 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
0x50 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
};
static void EPD_4IN2_4Gray_lut(void)
{
unsigned int count;
EPD_4IN2_SendCommand(0x20); //vcom
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_vcom[count]);}
EPD_4IN2_SendCommand(0x21); //red not use
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_ww[count]);}
EPD_4IN2_SendCommand(0x22); //bw r
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_bw[count]);}
EPD_4IN2_SendCommand(0x23); //wb w
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_wb[count]);}
EPD_4IN2_SendCommand(0x24); //bb b
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_bb[count]);}
EPD_4IN2_SendCommand(0x25); //vcom
for(count=0;count<42;count++)
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_ww[count]);}
}
static void drawNormal(void)
{
UWORD Width, Height;
Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
Height = EPD_4IN2_HEIGHT;
EPD_4IN2_SendCommand(0x10);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_SendData(0xFF);
}
}
EPD_4IN2_SendCommand(0x13);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_4IN2_SendData(((j + 1)*2 > Height) ? 0x00 : 0xFF);
}
}
EPD_4IN2_TurnOnDisplay();
}
static void draw4Gray(void)
{
UWORD Width, Height;
Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
Height = EPD_4IN2_HEIGHT;
EPD_4IN2_SendCommand(0x10);
for (UWORD i = 0; i < Width * Height; i++) {
UWORD idx = (i % 50) / 12;
if (idx > 3) idx = 3;
if (idx == 0 || idx == 1) {
EPD_4IN2_SendData(0x00);
} else if (idx == 2 || idx == 3) {
EPD_4IN2_SendData(0xFF);
}
}
EPD_4IN2_SendCommand(0x13);
for (UWORD i = 0; i < Width * Height; i++) {
UWORD idx = (i % 50) / 12;
if (idx > 3) idx = 3;
if (idx == 0 || idx == 2) {
EPD_4IN2_SendData(0x00);
} else if (idx == 1 || idx == 3) {
EPD_4IN2_SendData(0xFF);
}
}
// Load LUT from register
EPD_4IN2_SendCommand(0x00);
EPD_4IN2_SendData(0x3f);
EPD_4IN2_4Gray_lut();
EPD_4IN2_TurnOnDisplay();
// Load LUT from OTP
EPD_4IN2_SendCommand(0x00);
EPD_4IN2_SendData(0x1f);
}
void EPD_4in2_test(void)
{
DEV_Module_Init();
EPD_4IN2_Init();
EPD_4IN2_Clear();
DEV_Delay_ms(500);
drawNormal();
DEV_Delay_ms(1000);
draw4Gray();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 KiB

After

Width:  |  Height:  |  Size: 278 KiB

View File

@@ -18,6 +18,7 @@
#canvas-box { margin-top: 10px; }
button { padding: 0.375rem 0.75rem; border: 1px solid #0d6efd; border-radius: 0.375rem; }
button:disabled { opacity: 0.65; }
button.primary { color: #fff; background-color: #0d6efd; }
button.primary:hover { color: #fff; border-color: #0b5ed7; background-color: #0b5ed7; }
button.secondary { color: #fff; background-color: #6c757d; }
@@ -38,8 +39,8 @@
<legend>蓝牙</legend>
<div style="display: flex; justify-content: space-between;">
<div>
<button id="connectbutton" type="button" class="primary" onclick="preConnect();">连接</button>
<button id="reconnectbutton" type="button" class="secondary" onclick="reConnect();">重连</button>
<button id="connectbutton" type="button" class="primary" onclick="preConnect()">连接</button>
<button id="reconnectbutton" type="button" class="secondary" onclick="reConnect()">重连</button>
</div>
<div>
<label for="epddriver">驱动</label>
@@ -50,7 +51,7 @@
</select>
<label for="epdpins">引脚</label>
<input id="epdpins" type="text" value="">
<button id="setDriverbutton" type="button" class="primary" onclick="setDriver();">确认</button>
<button id="setDriverbutton" type="button" class="primary" onclick="setDriver()">确认</button>
</div>
</div>
</fieldset>
@@ -59,13 +60,13 @@
<legend>传图</legend>
<div style="margin-bottom: 10px; display: flex; justify-content: space-between;">
<div>
<button id="clearcanvasbutton" type="button" class="secondary" onclick="clear_canvas();">清除画布</button>
<button id="sendimgbutton" type="button" class="primary" class="primary" onclick="sendimg();">发送图片</button>
<button id="clearcanvasbutton" type="button" class="secondary" onclick="clear_canvas()">清除画布</button>
<button id="sendimgbutton" type="button" class="primary" onclick="sendimg()">发送图片</button>
</div>
<div>
<button id="clearscreenbutton" type="button" class="secondary" onclick="clearscreen();">清除屏幕</button>
<button id="clearscreenbutton" type="button" class="secondary" onclick="clearscreen()">清除屏幕</button>
<input type="text" id="cmdTXT" value="">
<button id="sendcmdbutton" type="button" class="primary" onclick="sendcmd(document.getElementById(&quot;cmdTXT&quot;).value);">发送命令</button>
<button id="sendcmdbutton" type="button" class="primary" onclick="sendcmd()">发送命令</button>
</div>
</div>
<div style="font-size: 85%; color: #666; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px dotted #AAA;"><b>状态:</b><span id="status"></span></div>
@@ -93,7 +94,7 @@
<label for="threshold">阈值</label>
<input type="number" max="255" min="0" value="125" id="threshold" onchange="update_image()">
</div>
<button type="button" class="secondary" onclick="document.getElementById('log').innerHTML = '';">清空日志</button>
<button type="button" class="secondary" onclick="clearLog()">清空日志</button>
</div>
<div style="display: flex; justify-content: space-between;">
<canvas id="canvas" width="400" height="300" style="border: black solid 1px;"></canvas>

View File

@@ -6,290 +6,319 @@ let reconnectTrys = 0;
let canvas;
let startTime;
let chunkSize = 38;
const MAX_PACKET_SIZE = 20;
const EpdCmd = {
SET_PINS: 0x00,
INIT: 0x01,
CLEAR: 0x02,
SEND_CMD: 0x03,
SEND_DATA: 0x04,
DISPLAY: 0x05,
SLEEP: 0x06,
SET_CONFIG: 0x90,
SYS_RESET: 0x91,
SYS_SLEEP: 0x92,
CFG_ERASE: 0x99,
};
function resetVariables() {
gattServer = null;
epdService = null;
epdCharacteristic = null;
document.getElementById("log").value = '';
gattServer = null;
epdService = null;
epdCharacteristic = null;
document.getElementById("log").value = '';
}
async function handleError(error) {
console.log(error);
resetVariables();
if (bleDevice == null)
return;
if (reconnectTrys <= 5) {
reconnectTrys++;
await connect();
}
else {
addLog("连接失败!");
reconnectTrys = 0;
}
console.log(error);
resetVariables();
if (bleDevice == null)
return;
if (reconnectTrys <= 5) {
reconnectTrys++;
await connect();
}
else {
addLog("连接失败!");
reconnectTrys = 0;
}
}
async function sendCommand(cmd) {
if (epdCharacteristic) {
await epdCharacteristic.writeValue(cmd);
} else {
addLog("服务不可用,请检查蓝牙连接");
}
async function write(cmd, data) {
if (!epdCharacteristic) {
addLog("服务不可用,请检查蓝牙连接");
return;
}
let payload = [cmd];
if (data) {
if (typeof data == 'string') data = hex2bytes(data);
if (data instanceof Uint8Array) data = Array.from(data);
payload.push(...data)
};
if (payload.length > MAX_PACKET_SIZE) {
throw new Error("BLE packet too large!");
}
addLog(`<span class="action">⇑</span> ${bytes2hex(payload)}`);
await epdCharacteristic.writeValue(Uint8Array.from(payload));
}
async function sendcmd(cmdTXT) {
addLog(`<span class="action">⇑</span> ${cmdTXT}`);
await sendCommand(hexToBytes(cmdTXT));
async function epdWrite(cmd, data) {
const chunkSize = MAX_PACKET_SIZE - 1;
const count = Math.round(data.length / chunkSize);
let chunkIdx = 0;
if (typeof data == 'string') data = hex2bytes(data);
await write(EpdCmd.SEND_CMD, [cmd]);
for (let i = 0; i < data.length; i += chunkSize) {
let currentTime = (new Date().getTime() - startTime) / 1000.0;
setStatus(`命令0x${cmd.toString(16)}, 数据块: ${chunkIdx+1}/${count+1}, 总用时: ${currentTime}s`);
await write(EpdCmd.SEND_DATA, data.slice(i, i + chunkSize));
chunkIdx++;
}
}
async function setDriver() {
const driver = document.getElementById("epddriver").value;
const pins = document.getElementById("epdpins").value;
await sendcmd(`00${pins}`);
await sendcmd(`01${driver}`);
await write(EpdCmd.SET_PINS, document.getElementById("epdpins").value);
await write(EpdCmd.INIT, document.getElementById("epddriver").value);
}
async function clearscreen() {
if(confirm('确认清除屏幕内容?')) {
await sendcmd("02");
}
if(confirm('确认清除屏幕内容?')) {
await write(EpdCmd.CLEAR);
}
}
async function sendCmWithData(cmd, data){
const count = Math.round(data.length / chunkSize);
let chunkIdx = 0;
await sendcmd(`03${cmd}`);
for (let i = 0; i < data.length; i += chunkSize) {
let currentTime = (new Date().getTime() - startTime) / 1000.0;
let chunk = data.substring(i, i + chunkSize);
setStatus(`命令0x${cmd}, 数据块: ${chunkIdx+1}/${count+1}, 总用时: ${currentTime}s`);
await sendcmd(`04${chunk}`);
chunkIdx++;
}
async function sendcmd() {
const cmdTXT = document.getElementById('cmdTXT').value;
if (cmdTXT == '') return;
const bytes = hex2bytes(cmdTXT);
await write(bytes[0], bytes.length > 1 ? bytes.slice(1) : null);
}
async function send4GrayLut() {
await sendCmWithData("20", "000A0000000160141400000100140000000100130A010001000000000000000000000000000000000000"); // vcom
await sendCmWithData("21", "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // red not use
await sendCmWithData("22", "400A0000000190141400000100140A000001990C01030401000000000000000000000000000000000000"); // bw r
await sendCmWithData("23", "400A0000000190141400000100140A000001990B04040101000000000000000000000000000000000000"); // wb w
await sendCmWithData("24", "800A0000000190141400000120140A000001501301000001000000000000000000000000000000000000"); // bb b
await sendCmWithData("25", "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // vcom
await epdWrite(0x20, "000A0000000160141400000100140000000100130A010001000000000000000000000000000000000000"); // vcom
await epdWrite(0x21, "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // red not use
await epdWrite(0x22, "400A0000000190141400000100140A000001990C01030401000000000000000000000000000000000000"); // bw r
await epdWrite(0x23, "400A0000000190141400000100140A000001990B04040101000000000000000000000000000000000000"); // wb w
await epdWrite(0x24, "800A0000000190141400000120140A000001501301000001000000000000000000000000000000000000"); // bb b
await epdWrite(0x25, "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // vcom
}
function getImageData(canvas, driver, mode) {
if (mode === '4gray') {
return bytesToHex(canvas2gray(canvas));
} else {
let data = bytesToHex(canvas2bytes(canvas, 'bw'));
if (driver === '03') {
if (mode.startsWith('bwr')) {
data += bytesToHex(canvas2bytes(canvas, 'red'));
} else {
const count = data.length;
data += 'F'.repeat(count);
}
}
return data;
}
if (mode === '4gray') {
return canvas2gray(canvas);
} else {
let data = canvas2bytes(canvas, 'bw');
if (driver === '03') {
if (mode.startsWith('bwr')) {
data.push(...canvas2bytes(canvas, 'red'));
} else {
const data1= 'F'.repeat(data.length);
data.push(...data1);
}
}
return data;
}
}
async function sendimg() {
startTime = new Date().getTime();
const canvas = document.getElementById("canvas");
const driver = document.getElementById("epddriver").value;
const mode = document.getElementById('dithering').value;
const imgArray = getImageData(canvas, driver, mode);
const bwArrLen = (canvas.width/8) * canvas.height * 2;
startTime = new Date().getTime();
const canvas = document.getElementById("canvas");
const driver = document.getElementById("epddriver").value;
const mode = document.getElementById('dithering').value;
const imgArray = getImageData(canvas, driver, mode);
const bwArrLen = canvas.width * canvas.height / 8;
if (imgArray.length == bwArrLen * 2) {
await sendCmWithData("10", imgArray.slice(0, bwArrLen - 1));
await sendCmWithData("13", imgArray.slice(bwArrLen));
} else {
await sendCmWithData(driver === "03" ? "10" : "13", imgArray);
}
if (imgArray.length == bwArrLen * 2) {
await epdWrite(0x10, imgArray.slice(0, bwArrLen));
await epdWrite(0x13, imgArray.slice(bwArrLen));
} else {
await epdWrite(driver === "03" ? 0x10 : 0x13, imgArray);
}
if (mode === "4gray") {
await sendcmd("0300");
await sendcmd("043F"); // Load LUT from register
await send4GrayLut();
await sendcmd("05");
await sendcmd("0300");
await sendcmd("041F"); // Load LUT from OTP
} else {
await sendcmd("05");
}
if (mode === "4gray") {
await epdWrite(0x00, [0x3F]); // Load LUT from register
await send4GrayLut();
await write(EpdCmd.DISPLAY);
await epdWrite(0x00, [0x1F]); // Load LUT from OTP
} else {
await write(EpdCmd.DISPLAY);
}
const sendTime = (new Date().getTime() - startTime) / 1000.0;
addLog(`发送完成!耗时: ${sendTime}s`);
setStatus(`发送完成!耗时: ${sendTime}s`);
const sendTime = (new Date().getTime() - startTime) / 1000.0;
addLog(`发送完成!耗时: ${sendTime}s`);
setStatus(`发送完成!耗时: ${sendTime}s`);
}
function updateButtonStatus() {
const connected = gattServer != null && gattServer.connected;
const status = connected ? null : 'disabled';
document.getElementById("reconnectbutton").disabled = (gattServer == null || gattServer.connected) ? 'disabled' : null;
document.getElementById("sendcmdbutton").disabled = status;
document.getElementById("clearscreenbutton").disabled = status;
document.getElementById("sendimgbutton").disabled = status;
document.getElementById("setDriverbutton").disabled = status;
const connected = gattServer != null && gattServer.connected;
const status = connected ? null : 'disabled';
document.getElementById("reconnectbutton").disabled = (gattServer == null || gattServer.connected) ? 'disabled' : null;
document.getElementById("sendcmdbutton").disabled = status;
document.getElementById("clearscreenbutton").disabled = status;
document.getElementById("sendimgbutton").disabled = status;
document.getElementById("setDriverbutton").disabled = status;
}
function disconnect() {
updateButtonStatus();
resetVariables();
addLog('已断开连接.');
document.getElementById("connectbutton").innerHTML = '连接';
updateButtonStatus();
resetVariables();
addLog('已断开连接.');
document.getElementById("connectbutton").innerHTML = '连接';
}
async function preConnect() {
if (gattServer != null && gattServer.connected) {
if (bleDevice != null && bleDevice.gatt.connected) {
await sendcmd("06");
bleDevice.gatt.disconnect();
}
}
else {
connectTrys = 0;
try {
bleDevice = await navigator.bluetooth.requestDevice({
optionalServices: ['62750001-d828-918d-fb46-b6c11c675aec'],
acceptAllDevices: true
});
} catch (e) {
if (e.message) addLog(e.message);
return;
}
if (gattServer != null && gattServer.connected) {
if (bleDevice != null && bleDevice.gatt.connected) {
await write(EpdCmd.SLEEP);
bleDevice.gatt.disconnect();
}
}
else {
connectTrys = 0;
try {
bleDevice = await navigator.bluetooth.requestDevice({
optionalServices: ['62750001-d828-918d-fb46-b6c11c675aec'],
acceptAllDevices: true
});
} catch (e) {
if (e.message) addLog(e.message);
return;
}
await bleDevice.addEventListener('gattserverdisconnected', disconnect);
try {
await connect();
} catch (e) {
await handleError(e);
}
}
await bleDevice.addEventListener('gattserverdisconnected', disconnect);
try {
await connect();
} catch (e) {
await handleError(e);
}
}
}
async function reConnect() {
connectTrys = 0;
if (bleDevice != null && bleDevice.gatt.connected)
bleDevice.gatt.disconnect();
resetVariables();
addLog("正在重连");
setTimeout(async function () { await connect(); }, 300);
connectTrys = 0;
if (bleDevice != null && bleDevice.gatt.connected)
bleDevice.gatt.disconnect();
resetVariables();
addLog("正在重连");
setTimeout(async function () { await connect(); }, 300);
}
async function connect() {
if (epdCharacteristic == null && bleDevice != null) {
addLog("正在连接: " + bleDevice.name);
if (epdCharacteristic == null && bleDevice != null) {
addLog("正在连接: " + bleDevice.name);
gattServer = await bleDevice.gatt.connect();
addLog(' 找到 GATT Server');
gattServer = await bleDevice.gatt.connect();
addLog(' 找到 GATT Server');
epdService = await gattServer.getPrimaryService('62750001-d828-918d-fb46-b6c11c675aec');
addLog(' 找到 EPD Service');
epdService = await gattServer.getPrimaryService('62750001-d828-918d-fb46-b6c11c675aec');
addLog(' 找到 EPD Service');
epdCharacteristic = await epdService.getCharacteristic('62750002-d828-918d-fb46-b6c11c675aec');
addLog(' 找到 Characteristic');
epdCharacteristic = await epdService.getCharacteristic('62750002-d828-918d-fb46-b6c11c675aec');
addLog(' 找到 Characteristic');
await epdCharacteristic.startNotifications();
epdCharacteristic.addEventListener('characteristicvaluechanged', (event) => {
addLog(`<span class="action">⇓</span> ${bytesToHex(event.target.value.buffer)}`);
document.getElementById("epdpins").value = bytesToHex(event.target.value.buffer.slice(0, 7));
document.getElementById("epddriver").value = bytesToHex(event.target.value.buffer.slice(7, 8));
});
await epdCharacteristic.startNotifications();
epdCharacteristic.addEventListener('characteristicvaluechanged', (event) => {
addLog(`<span class="action">⇓</span> ${bytes2hex(event.target.value.buffer)}`);
document.getElementById("epdpins").value = bytes2hex(event.target.value.buffer.slice(0, 7));
document.getElementById("epddriver").value = bytes2hex(event.target.value.buffer.slice(7, 8));
});
await sendcmd("01");
await write(EpdCmd.INIT);
document.getElementById("connectbutton").innerHTML = '断开';
updateButtonStatus();
}
document.getElementById("connectbutton").innerHTML = '断开';
updateButtonStatus();
}
}
function setStatus(statusText) {
document.getElementById("status").innerHTML = statusText;
document.getElementById("status").innerHTML = statusText;
}
function addLog(logTXT) {
const log = document.getElementById("log");
const now = new Date();
const time = String(now.getHours()).padStart(2, '0') + ":" +
String(now.getMinutes()).padStart(2, '0') + ":" +
String(now.getSeconds()).padStart(2, '0') + " ";
log.innerHTML += '<span class="time">' + time + '</span>' + logTXT + '<br>';
log.scrollTop = log.scrollHeight;
while ((log.innerHTML.match(/<br>/g) || []).length > 20) {
var logs_br_position = log.innerHTML.search("<br>");
log.innerHTML = log.innerHTML.substring(logs_br_position + 4);
log.scrollTop = log.scrollHeight;
}
const log = document.getElementById("log");
const now = new Date();
const time = String(now.getHours()).padStart(2, '0') + ":" +
String(now.getMinutes()).padStart(2, '0') + ":" +
String(now.getSeconds()).padStart(2, '0') + " ";
log.innerHTML += '<span class="time">' + time + '</span>' + logTXT + '<br>';
log.scrollTop = log.scrollHeight;
while ((log.innerHTML.match(/<br>/g) || []).length > 20) {
var logs_br_position = log.innerHTML.search("<br>");
log.innerHTML = log.innerHTML.substring(logs_br_position + 4);
log.scrollTop = log.scrollHeight;
}
}
function hexToBytes(hex) {
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return new Uint8Array(bytes);
function clearLog() {
document.getElementById("log").innerHTML = '';
}
function bytesToHex(data) {
return new Uint8Array(data).reduce(
function (memo, i) {
return memo + ("0" + i.toString(16)).slice(-2);
}, "");
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);
let stringOut = ("0000" + intIn.toString(16)).substr(-4)
return stringOut.substring(2, 4) + stringOut.substring(0, 2);
}
async function update_image () {
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let image = new Image();;
const image_file = document.getElementById('image_file');
if (image_file.files.length > 0) {
const file = image_file.files[0];
image.src = URL.createObjectURL(file);
} else {
image.src = document.getElementById('demo-img').src;
}
let image = new Image();;
const image_file = document.getElementById('image_file');
if (image_file.files.length > 0) {
const file = image_file.files[0];
image.src = URL.createObjectURL(file);
} else {
image.src = document.getElementById('demo-img').src;
}
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()
}
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()
}
}
function clear_canvas() {
if(confirm('确认清除画布内容?')) {
const ctx = canvas.getContext("2d");
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
if(confirm('确认清除画布内容?')) {
const ctx = canvas.getContext("2d");
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
function convert_dithering() {
const ctx = canvas.getContext("2d");
const mode = document.getElementById('dithering').value;
if (mode.startsWith('bwr')) {
ditheringCanvasByPalette(canvas, bwrPalette, mode);
} else if (mode === '4gray') {
dithering(ctx, canvas.width, canvas.height, 4, "gray");
} else {
dithering(ctx, canvas.width, canvas.height, parseInt(document.getElementById('threshold').value), mode);
}
const ctx = canvas.getContext("2d");
const mode = document.getElementById('dithering').value;
if (mode.startsWith('bwr')) {
ditheringCanvasByPalette(canvas, bwrPalette, mode);
} else if (mode === '4gray') {
dithering(ctx, canvas.width, canvas.height, 4, "gray");
} else {
dithering(ctx, canvas.width, canvas.height, parseInt(document.getElementById('threshold').value), mode);
}
}
document.body.onload = () => {
canvas = document.getElementById('canvas');
canvas = document.getElementById('canvas');
updateButtonStatus();
update_image();
updateButtonStatus();
update_image();
document.getElementById('dithering').value = 'none';
document.getElementById('dithering').value = 'none';
}