前端Excel热成像数据展示及插值算法
🎬 江城开朗的豌豆:个人主页
🔥 个人专栏:《 VUE 》 《 javaScript 》
📝 个人网站 :《 江城开朗的豌豆🫛 》
⛺️生活的理想,就是为了理想的生活!
目录
📘 前言
📘一、热成像数据的导入与展示
📟 1.数据导入:
📟 2.创建热图:
📟3.数据可视化
📘二、插值算法的应用
📟 1.线性插值:
📟 2.双线性插值:
📟 3.样条插值:
📘三、实例操作
📘 完整代码展示
📘 写在最后
📘 前言
热成像技术在工业、医学和科学研究中发挥了重要作用,它能够通过捕捉不同物体的温度分布图像来提供宝贵的信息。然而,要有效地展示和分析这些热成像数据,我们需要使用适当的工具和算法。本文将介绍如何使用Excel展示热成像数据,并实现插值算法以增强数据分析的准确性和可视化效果。
原始图
转换成功的效果图
📘一、热成像数据的导入与展示
热成像设备通常生成的是包含温度信息的二维数组数据。在Excel中展示这些数据,可以通过以下步骤
📟 1.数据导入:
将热成像数据以CSV或XLSX格式导入Excel。通常,这些数据以矩阵的形式存储,每个单元格代表一个温度值。
📟 2.创建热图:
在Excel中,可以使用条件格式来创建热图。选择包含温度数据的单元格区域,应用“条件格式”中的“色阶”功能,以不同的颜色表示不同的温度范围。这种可视化方法能帮助快速识别热图中的热点区域。
📟3.数据可视化
利用Excel的图表工具,将数据以图表形式展示。例如,可以创建散点图或折线图,帮助分析温度随时间或位置的变化
📘二、插值算法的应用
在热成像数据中,可能存在一些缺失值或数据点稀疏的情况。插值算法可以帮助我们估算这些缺失值,并提高数据的连续性。以下是一些常见的插值算法及其在Excel中的实现方法:
📟 1.线性插值:
线性插值是最简单的插值方法,通过连接已知数据点的直线来估算未知点的值。在Excel中,可以通过线性回归或在两个已知数据点之间插入一个新的数据点来实现。
📟 2.双线性插值:
双线性插值适用于二维数据,使用已知点形成的矩阵进行插值。你可以在Excel中创建一个新的数据表,通过公式计算每个数据点的插值值。双线性插值公式如下:
📟 3.样条插值:
样条插值是一种更复杂的插值方法,通过多项式拟合数据点,实现平滑的曲线插值。在Excel中,这种方法可以通过插件或VBA代码实现,虽然设置相对复杂,但可以生成更平滑的数据图。
📘三、实例操作
假设我们有一个包含热成像数据的Excel表格,我们可以通过以下步骤进行插值和数据展示:
-
创建数据表: 将热成像数据输入Excel,并使用条件格式创建热图。
-
应用插值算法: 使用Excel的插值公式填补缺失数据,或通过VBA实现更复杂的插值算法。
-
数据分析与优化: 根据插值后的数据,生成更精确的热图和图表。利用Excel的数据分析工具,评估数据的准确性和可靠性。
📘 完整代码展示
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Excel Heatmap with Canvas</title><script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script><style>#heatmapCanvas {/* border: 1px solid black; */}</style></head><body><button onclick="chuNenFx()">储能分析</button><input type="file" id="fileInput" /><input type="number" id="reLiNum" placeholder="输入数字" /><button onclick="getValue()">获取值</button> <button onclick="showMaxTemperature()">显示最高温度</button><button onclick="showMinTemperature()">显示最低温度</button><br /><button onclick="highlightMaxTemperature()">标记最高温度</button><button onclick="highlightMinTemperature()">标记最低温度</button><canvas id="heatmapCanvas"></canvas><script>document.getElementById("fileInput").addEventListener("change", handleFileSelect, false);// 双线性插值算法var newData = [];function processFile() {const fileInput = document.getElementById("fileInput");const file = fileInput.files[0];const reader = new FileReader();reader.onload = function (event) {const data = new Uint8Array(event.target.result);const workbook = XLSX.read(data, { type: "array" });const sheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[sheetName];const csv = XLSX.utils.sheet_to_csv(worksheet);const arrayData = csvToArray(csv);const interpolatedData = interpolate22(arrayData, 480, 640); // 增加到 240, 320 的分辨率 1440, 1920 -- 384, 512// console.log("Interpolated", interpolatedData);const szNew = interpolatedData.map((row) => row.map((cell) => Math.round(cell))).map((row) => row.filter((cell) => cell !== 0) // 过滤掉值为 0 的元素);console.log(szNew);newData = szNew;};reader.readAsArrayBuffer(file);}function interpolate22(data, newRows, newCols) {const rows = data.length;const cols = data[0].length;const interpolatedData = Array.from({ length: newRows }, () =>Array(newCols).fill(0));for (let i = 0; i < newRows; i++) {for (let j = 0; j < newCols; j++) {const xRatio = (j / (newCols - 1)) * (cols - 1);const yRatio = (i / (newRows - 1)) * (rows - 1);const x0 = Math.floor(xRatio);const x1 = Math.min(x0 + 1, cols - 1);const y0 = Math.floor(yRatio);const y1 = Math.min(y0 + 1, rows - 1);const q11 = data[y0][x0];const q21 = data[y0][x1];const q12 = data[y1][x0];const q22 = data[y1][x1];const r1 = (x1 - xRatio) * q11 + (xRatio - x0) * q21;const r2 = (x1 - xRatio) * q12 + (xRatio - x0) * q22;interpolatedData[i][j] = (y1 - yRatio) * r1 + (yRatio - y0) * r2;}}return interpolatedData;}// 最大值function getMaxTemperature(data) {let maxTemp = -Infinity;for (const row of data) {for (const temp of row) {if (temp > maxTemp) {maxTemp = temp;}}}return maxTemp;}// 插值算法封装function interpolate(data, newRows, newCols) {const rows = data.length;const cols = data[0].length;const x = Array.from({ length: cols }, (_, i) => i);const y = Array.from({ length: rows }, (_, i) => i);const interpolatedData = Array.from({ length: newRows }, (_, i) => {return Array.from({ length: newCols }, (_, j) => {const xRatio = (j / (newCols - 1)) * (cols - 1);const yRatio = (i / (newRows - 1)) * (rows - 1);const x0 = Math.floor(xRatio);const x1 = Math.min(x0 + 1, cols - 1);const y0 = Math.floor(yRatio);const y1 = Math.min(y0 + 1, rows - 1);const q11 = data[y0][x0];const q21 = data[y0][x1];const q12 = data[y1][x0];const q22 = data[y1][x1];const r1 = (x1 - xRatio) * q11 + (xRatio - x0) * q21;const r2 = (x1 - xRatio) * q12 + (xRatio - x0) * q22;return (y1 - yRatio) * r1 + (yRatio - y0) * r2;});});return interpolatedData;}function csvToArray(text) {return text.split("\n").map((row) => row.split(",").map(Number));}var maxTemperature = [];// 最小值function getMinTemperature(data) {let minTemp = Infinity;for (const row of data) {for (const temp of row) {if (temp < minTemp) {minTemp = temp;}}}return minTemp;}// 显示最低温度function showMinTemperature() {const minTemperature = getMinTemperature(maxTemperature);alert(`最低温度是: ${minTemperature / 100}°C`);}function showMaxTemperature() {if (maxTemperature.length > 0) {const maxTempe = getMaxTemperature(maxTemperature);alert(`最高温度是: ${maxTempe / 100}°C`);} else {alert(`最高温度是: 请先上传数据`);}}// 封装双线性插值算法function bilinearInterpolate(x, y, values) {const x1 = Math.floor(x);const y1 = Math.floor(y);const x2 = Math.ceil(x);const y2 = Math.ceil(y);const Q11 = values[y1] ? values[y1][x1] : 0;const Q12 = values[y1] ? values[y1][x2] : 0;const Q21 = values[y2] ? values[y2][x1] : 0;const Q22 = values[y2] ? values[y2][x2] : 0;const xFraction = x - x1;const yFraction = y - y1;const R1 = Q11 * (1 - xFraction) + Q12 * xFraction;const R2 = Q21 * (1 - xFraction) + Q22 * xFraction;return R1 * (1 - yFraction) + R2 * yFraction;}// 获取excel数据async function handleFileSelect(event, json) {await processFile();const file = event.target.files[0];// console.log("=====>>>", file);if (!file) return;const reader = new FileReader();reader.onload = function (e) {const data = new Uint8Array(e.target.result);const workbook = XLSX.read(data, { type: "array" });// Assuming you want to process the first sheetconst sheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[sheetName];// const json = XLSX.utils.sheet_to_json(worksheet, {// header: 1,// defval: 0,// });// Default values for empty cells// Convert data to 2D array// console.log("===========json=====================", json);const dataArray = newData.map((row) =>row.map((cell) => parseFloat(cell) || 0));// console.log("Data Array:", dataArray);maxTemperature = dataArray;// console.log("=workbook===" + maxTemperature);drawHeatmap(dataArray);};reader.readAsArrayBuffer(file);}// 插值算法const canvas = document.getElementById("heatmapCanvas");// const cellSize = 10; // 原始单元格大小let newCellSize = 1; // 插值后的单元格大小function getValue() {const inputElement = document.getElementById("reLiNum");const value = inputElement.value; // 获取输入的值newCellSize = value;drawHeatmap(maxTemperature); // 重新绘制热力图}// 页面跳转function chuNenFx() {window.location.replace("./boxEchars.html");}// 绘制热力图function drawHeatmap(dataArray) {const width = dataArray[0].length;const height = dataArray.length;// 计算新画布的宽度和高度const canvasWidth = width * newCellSize;const canvasHeight = height * newCellSize;// Adjust canvas sizecanvas.width = canvasWidth; // Scale widthcanvas.height = canvasHeight; // Scale heightconst ctx = canvas.getContext("2d");const imageData = ctx.createImageData(canvasWidth, canvasHeight);// 查找归一化的最小值和最大值let min = Infinity;let max = -Infinity;dataArray.flat().forEach((value) => {if (value < min) min = value;if (value > max) max = value;});// 生成热力图for (let y = 0; y < canvasHeight; y++) {for (let x = 0; x < canvasWidth; x++) {const dataX = x / newCellSize;const dataY = y / newCellSize;const value = bilinearInterpolate(dataX, dataY, dataArray);// const value = dataArray[y][x];const normalizedValue = (value - min) / (max - min);// for (let dy = 0; dy < cellSize; dy++) {// for (let dx = 0; dx < cellSize; dx++) {// const index = ((y * cellSize + dy) * canvas.width + (x * cellSize + dx)) * 4;// const color = getHeatmapColor(normalizedValue);// imageData.data[index] = color[0];// imageData.data[index + 1] = color[1];// imageData.data[index + 2] = color[2];// imageData.data[index + 3] = 255;// }// }// // 获取颜色值const color = getHeatmapColor(normalizedValue);// 设置画布上的像素颜色const index = (y * canvasWidth + x) * 4;imageData.data[index] = color[0]; // RedimageData.data[index + 1] = color[1]; // GreenimageData.data[index + 2] = color[2]; // BlueimageData.data[index + 3] = 255; // Alpha}}// console.log("imageDat", imageData);ctx.putImageData(imageData, 0, 0);}// 找到最高温度及其位置function getMaxTemperatureInfo(isMax) {let extremeTemp = isMax ? -Infinity : Infinity;let position = { row: 0, col: 0 };maxTemperature.forEach((row, rowIndex) => {row.forEach((temp, colIndex) => {if ((isMax && temp > extremeTemp) ||(!isMax && temp < extremeTemp)) {extremeTemp = temp;position = { row: rowIndex, col: colIndex };}});});return { extremeTemp, position };}// 找到最高温度及其位置// function getMaxTemperatureInfo() {// let maxTemp = -Infinity;// let position = { row: 0, col: 0 };// maxTemperature.forEach((row, rowIndex) => {// row.forEach((temp, colIndex) => {// if (temp > maxTemp) {// maxTemp = temp;// position = { row: rowIndex, col: colIndex };// }// });// });// return { maxTemp, position };// }// 标记最高温度function highlightMaxTemperature() {const { extremeTemp, position } = getMaxTemperatureInfo(true);drawHeatmap(maxTemperature); // 重新绘制热力图const ctx = canvas.getContext("2d");// 绘制标记ctx.strokeStyle = "yellow";ctx.lineWidth = 30;ctx.beginPath();const x = position.col * newCellSize + newCellSize / 2;const y = position.row * newCellSize + newCellSize / 2;ctx.arc(x, y, newCellSize / 4, 0, 2 * Math.PI);ctx.stroke();ctx.fillStyle = "yellow";ctx.fill();// alert(`最高温度是: ${extremeTemp/100}°C`);// 显示温度值ctx.fillStyle = "black";ctx.font = "12px Arial";ctx.textAlign = "center";ctx.textBaseline = "middle";ctx.fillText(`${extremeTemp / 100}°C`, x, y);}// 标记最低温度function highlightMinTemperature() {const { extremeTemp, position } = getMaxTemperatureInfo(false);drawHeatmap(maxTemperature); // 重新绘制热力图const ctx = canvas.getContext("2d");// 绘制标记ctx.strokeStyle = "green";ctx.lineWidth = 30;ctx.beginPath();const x = position.col * newCellSize + newCellSize / 2;const y = position.row * newCellSize + newCellSize / 2;ctx.arc(x, y, newCellSize / 4, 0, 2 * Math.PI);ctx.stroke();ctx.fillStyle = "green";ctx.fill();// alert(`最低温度是: ${extremeTemp/100}°C`);// 显示温度值ctx.fillStyle = "white";ctx.font = "12px Arial";ctx.textAlign = "center";ctx.textBaseline = "middle";ctx.fillText(`${extremeTemp / 100}°C`, x, y);}function getHeatmapColor(value) {// 从蓝色到红色的简单热图颜色渐变const r = Math.min(255, Math.max(0, Math.floor(255 * value)));const g = Math.min(255, Math.max(0, Math.floor(255 * (1 - value))));const b = 0;return [r, g, b];}</script></body>
</html>
📘 写在最后
Excel作为一种强大的数据处理工具,可以有效地展示和分析热成像数据。通过合理使用插值算法,可以提升数据的连续性和可视化效果。希望本文能帮助你更好地利用Excel进行热成像数据的展示和分析。如果你有更复杂的数据需求,也可以考虑结合使用专业的数据分析工具和编程语言。
通过掌握这些基本技巧,你将能够更好地理解和利用热成像数据,为你的工作和研究提供有力支持。
感谢大家一如既往对我的点赞与支持,不是我的作品有多好,而是你们的不嫌弃。这世界上有一种爱叫“关注”,感恩遇见、感恩有你~
相关文章:

前端Excel热成像数据展示及插值算法
🎬 江城开朗的豌豆:个人主页 🔥 个人专栏:《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️生活的理想,就是为了理想的生活! 目录 📘 前言 📘一、热成像数…...

VBA_NZ系列工具NZ01: VBA二维码应用技术
我的教程一共九套及VBA汉英手册一部,分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的入门,到数据库,到字典,到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑,这么多知识点该如何组织…...

小明震惊OpenAI 的新模型 01
在硅谷的中心,繁忙的咖啡馆和创业中心周围,年轻的软件工程师小明坐在他的办公桌前,面露困惑。科技界一直在盛传一项新的AI突破,但他持怀疑态度,不敢抱太大希望。他认为AI泡沫即将破灭,炒作列车即将出轨&…...

Clickhouse使用笔记
clickhouse官方文档:https://clickhouse.com/docs/zh/sql-reference/data-types/decimal 一,建表 create table acitivity_user_record ( id String DEFAULT generateUUIDv4(), -- 主键自增 activityId String, userId String, userName Nullable(Strin…...

基于高通主板的ARM架构服务器
一、ARM架构服务器的崛起 (一)市场需求推动 消费市场寒冬,全球消费电子需求下行,服务器成半导体核心动力之一。Arm 加速布局服务器领域,如 9 月推出 Neoverse V2。长久以来,x86 架构主导服务器市场&#…...

AV1 Bitstream Decoding Process Specification--[2]:符号和缩写术语
原文地址:https://aomediacodec.github.io/av1-spec/av1-spec.pdf没有梯子的下载地址:AV1 Bitstream & Decoding Process Specification摘要:这份文档定义了开放媒体联盟(Alliance for Open Media)AV1视频编解码器…...

【Python爬虫系列】_022.异步文件操作aiofiles
课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈...

GD32E230 RTC报警中断功能使用
GD32E230 RTC报警中断使用 GD32E230 RTC时钟源有3个,一个是内部RC振动器产生的40KHz作为时钟源,或者是有外部32768Hz晶振.,或者外部高速时钟晶振分频作为时钟源。 🔖个人认为最难理解难点的就是有关RTC时钟异步预分频和同步预分频的计算。在对…...
C/C++语言基础--从C到C++的不同(上)
本专栏目的 更新C/C的基础语法,包括C的一些新特性 前言 之前更新的C语言,感谢大家的点赞收藏关注,接下来我们逐步也开始更新C;C语言后面也会继续更新知识点,如内联汇编;本人现在正在写一个C语言的图书管理系…...

自动驾驶自动泊车场景应用总结
自动泊车技术是当前智能驾驶技术的一个重要分支,其目标是通过车辆自身的感知、决策和控制系统,实现车辆在有限空间内的自主泊车操作。目前自动泊车可分为半自动泊车、全自动泊车、记忆泊车、自主代客泊车四种产品形态,其中, 根据搭载传感器和使用场景的不同,全自动泊车又可…...

redis常见的数据类型?
参考:一文读懂Redis五种数据类型及应用场景 - 知乎 (zhihu.com) String 类型 String 类型:Redis 最基本的数据类型,它是二进制安全的,意味着你可以用它来存储任何类型的数据,如图片、序列化对象等。使用场景ÿ…...

TCP Analysis Flags 之 TCP ZeroWindow
前言 默认情况下,Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态,并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时,会对每个 TCP 数据包进行一次分析,数据包按照它们在数据包列表中出现的顺序进行处理。可…...

[产品管理-16]:NPDP新产品开发 - 14 - 产品创新流程 - 产品创新流程模型比较:门径、IPD、精益生产、敏捷、系统工程、设计思维、精益创业
目录 一、精益开发与敏捷开发的比较 1、核心理念 2、实践方式 3、应用场景 4、总结 二、门径流程 VS 敏捷方法 1、定义与特点 门径管理流程 敏捷方法 2、应用场景 3、比较 4、总结 三、集成产品开发 VS 系统工程 VS 设计思维 1、集成产品开发(IPD&…...
postgresql 导出CSV格式数据
方法一 psql -c 导出 导出的文件存放在执行psql的客户端。 psql -h 127.0.0.1 -p 5432 -U postgres postgres -Atqc "select oid,relname,relnamespace from tmp_t0 " --csv -o /tmp/test.csv方法二 psql -f 导出 导出的文件存放在执行psql的客户端。 如果查询很长…...

【C++】STL--string(上)
前言 C语言中,字符串是以\0结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留…...

【C++】Stack
个人主页~ Stack 一、Stack的介绍和使用1、stack的介绍2、stack的使用3、stack的模拟实现 二、容器适配器1、什么是适配器2、容器适配器的使用 三、deque1、原理介绍2、deque的使用3、deque的缺陷 一、Stack的介绍和使用 1、stack的介绍 stack详细解释 stack是一种容器适配器…...

“药乡”怀化,按下产业向海“加速键”
怀化,这座被火车拖来的城市,拥有什么独特的产业优势吗? 很多人不知道的是,怀化在整个医药领域可是大名鼎鼎的“中国道地药材之乡”,中药材资源蕴藏量居湖南省第一。尤其是怀化靖州,这里年集散茯苓11万吨&a…...

【AWDP】 AWDP 赛制详解应对方法赛题实践 量大管饱
文章首发于【先知社区】:https://xz.aliyun.com/t/15535 一、AWDP概述 AWDP是什么 AWDP是一种综合考核参赛团队攻击、防御技术能力、即时策略的攻防兼备比赛模式。每个参赛队互为攻击方和防守方,充分体现比赛的实战性、实时性和对抗性,对参…...

读构建可扩展分布式系统:方法与实践05分布式缓存
1. 分布式缓存 1.1. 缓存存在于应用程序的许多地方 1.1.1. 行应用程序的CPU具有高速多级硬件缓存,可以减少相对较慢的主内存访问 1.1.2. 数据库引擎可以利用主内存来缓存数据存储的内容,这样在许多情况下查询就可以不用访问速度相对较慢的磁盘 1.2. …...

【逐行注释】自适应Q和R的AUKF(自适应无迹卡尔曼滤波),附下载链接
文章目录 自适应Q的KF逐行注释的说明运行结果部分代码各模块解释 自适应Q的KF 自适应无迹卡尔曼滤波(Adaptive Unscented Kalman Filter,AUKF)是一种用于状态估计的滤波算法。它是基于无迹卡尔曼滤波(Unscented Kalman Filter&am…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...