前端二进制数据指南:从 ArrayBuffer 到高级流处理

前端开发中,二进制数据是处理文件、图像、音视频、网络通信等场景的基础。以下是核心概念和用途的通俗解释:

前端二进制数据介绍

1. 什么是前端二进制数据?

指计算机原始的 0 和 1 格式的数据(比如一张图片的底层代码),前端通过特定 API 操作这些数据。


2. 核心用途

  • 文件操作
    上传/下载文件(如用户传图片)、切片大文件(断点续传)。

  • 图像处理
    修改图片像素(滤镜、裁剪)、Canvas 绘图。

  • 网络通信
    WebSocket 传输二进制帧、AJAX 上传二进制数据。

  • 高性能计算
    WebAssembly 运行编译型代码(如游戏、加密算法)。


3. 关键 API 速览

API作用示例场景
ArrayBuffer存储原始二进制数据文件解析、网络数据接收
Uint8Array按字节操作数据(8位无符号整数)图像像素处理
Blob表示文件类数据(不可变)文件分片上传
FileReader读取本地文件内容图片预览(转Base64)
Canvas操作图像像素数据实时滤镜效果

4. 为什么需要二进制操作?

  • 性能更高:直接操作内存,比文本处理快。

  • 功能更强:实现文件编辑、音视频解码等复杂功能。

  • 节省带宽:二进制比文本格式(如JSON)体积更小。

前端二进制数据核心类型对比表

类型/API继承关系使用场景核心优势
ArrayBuffer基础容器,无继承关系存储原始二进制数据,如网络传输、文件解析、WebAssembly 内存操作直接操作内存,性能极高
TypedArray基于 ArrayBuffer 的视图(如 Uint8Array类型化数据处理(图像像素、音频采样、网络协议解析)类型明确,自动处理字节对齐,简化操作
DataView基于 ArrayBuffer 的视图处理混合数据类型或需要控制字节序的场景(如解析二进制文件格式、网络协议)灵活读写不同数据类型,支持手动控制字节序
Blob无继承关系处理不可变的类文件数据(文件分片上传、生成临时 URL)支持大文件分片(Blob.slice()),可直接用于 fetch 或 FormData
File继承自 Blob表示用户上传的本地文件(通过 <input type="file"> 获取)包含文件名、类型、修改时间等元信息
FileReader无继承关系异步读取 Blob 或 File 内容(转为 ArrayBufferDataURL、文本等)支持多种读取格式,兼容浏览器文件操作
ImageData包含 Uint8ClampedArray操作 Canvas 像素数据(图像滤镜、特效处理)直接映射到 Canvas 像素,RGBA 格式标准化
Streams API基于 ReadableStream/WritableStream流式处理大文件(如视频分块加载、实时数据传输)分块处理数据,避免内存溢出,提升性能
WebAssembly通过 ArrayBuffer 加载模块高性能计算(游戏、音视频编码、密码学算法)接近原生代码性能,支持 C/C++/Rust 编译运行

二进制数据核心类型关键关联说明

  1. 继承链

    • File → Blob → 所有文件相关操作基于 Blob 扩展。

    • TypedArray/DataView → ArrayBuffer → 所有类型化操作依赖原始二进制缓冲区。

  2. 协作流程示例

    • 文件上传
      File → FileReader → ArrayBuffer → TypedArray(处理数据) → fetch 上传。

    • 图像处理
      Blob → Image → Canvas → ImageData(像素操作) → 显示结果。

    • WebAssembly
      .wasm → ArrayBuffer → 编译实例化 → 调用高性能函数。

 快速对比示例

// 1. Blob → ArrayBuffer → TypedArray
const blob = new Blob([new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f])]); // "Hello"
blob.arrayBuffer().then(buffer => {const uint8 = new Uint8Array(buffer);console.log(uint8); // Uint8Array(5) [72, 101, 108, 108, 111]
});// 2. File → FileReader → ArrayBuffer
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (e) => {const file = e.target.files[0];const reader = new FileReader();reader.onload = () => {const buffer = reader.result;const dataView = new DataView(buffer);console.log("文件头:", dataView.getUint32(0));};reader.readAsArrayBuffer(file);
});

二进制数据核心类型总结

  • 底层核心ArrayBuffer 是二进制操作的基础,其他类型均围绕它扩展。

  • 文件处理Blob 和 File 用于文件级操作,FileReader 提供读取能力。

  • 数据视图TypedArray 和 DataView 提供灵活的内存操作方式。

  • 高性能场景WebAssembly 和 Streams API 解决计算和流式处理需求。

前端常用二进制数据介绍

1. ArrayBuffer

作用:最基础的二进制数据容器,表示通用的、固定长度的原始二进制数据缓冲区,不能直接操作,需通过 TypedArray 或 DataView 访问
优势:直接操作内存,性能极高,适合处理音频、视频等二进制数据。
使用场景:网络传输、文件解析、WebAssembly 内存操作。

区分:Buffer是Node.js 特有的二进制类型(等同于 Uint8Array),前端通常通过浏览器 API 或工具库(如 buffer polyfill)使用

<!DOCTYPE html>
<html>
<head><title>ArrayBuffer 示例</title>
</head>
<body><script>// 1. 创建一个 16 字节的 ArrayBufferconst buffer = new ArrayBuffer(16);// 2. 使用 TypedArray 操作数据const int32View = new Int32Array(buffer); // 每个元素占 4 字节int32View[0] = 42;                        // 写入数据int32View[1] = 1024;// 3. 通过另一个视图验证数据const uint8View = new Uint8Array(buffer);console.log("ArrayBuffer 内容(十六进制):");for (let i = 0; i < uint8View.length; i++) {console.log(uint8View[i].toString(16).padStart(2, '0'));}</script>
</body>
</html>

2. TypedArray

作用

  • 基于 ArrayBuffer 的视图,提供特定类型的二进制数据操作,包括:

    • Int8ArrayUint8Array(无符号字节)

    • Uint8ClampedArray(限制在 0-255,常用于图像处理)

    • Int16ArrayUint16Array

    • Int32ArrayUint32Array

    • Float32ArrayFloat64Array

    • BigInt64ArrayBigUint64Array(ES2020 引入,用于大整数)

优势:类型明确,无需手动处理字节细节。
使用场景:图像像素操作、音频数据处理。

<!DOCTYPE html>
<html>
<head><title>TypedArray 示例</title>
</head>
<body><script>// 1. 创建一个 4 字节的 ArrayBufferconst buffer = new ArrayBuffer(4);// 2. 使用不同类型视图操作同一 bufferconst uint8View = new Uint8Array(buffer);uint8View[0] = 0x12;  // 写入字节数据uint8View[1] = 0x34;const uint16View = new Uint16Array(buffer);console.log("Uint16 视图的值:", uint16View[0].toString(16)); // 输出 3412(小端序)const uint32View = new Uint32Array(buffer);console.log("Uint32 视图的值:", uint32View[0].toString(16)); // 输出 34120000</script>
</body>
</html>

3. DataView

作用:灵活读写 ArrayBuffer,支持混合数据类型和字节序控制。
优势:处理复杂二进制格式时更灵活。
使用场景:解析自定义协议、处理网络数据包

<!DOCTYPE html>
<html>
<head><title>DataView 示例</title>
</head>
<body><script>// 1. 创建一个 8 字节的 ArrayBufferconst buffer = new ArrayBuffer(8);const view = new DataView(buffer);// 2. 写入不同数据类型(大端序)view.setInt32(0, 0x12345678, false);  // 大端序写入 4 字节整数view.setFloat32(4, Math.PI, false);   // 大端序写入浮点数// 3. 读取数据console.log("整数:", view.getInt32(0, false).toString(16));console.log("浮点数:", view.getFloat32(4, false));</script>
</body>
</html>

4. Blob (Binary Large Object)

作用:不可变的类文件对象,常用于文件切片(slice())、下载或上传(如 fetch 的 FormData)
优势:适合处理大文件,可直接用于网络请求。
使用场景:文件下载、图片预览。

<!DOCTYPE html>
<html>
<body><button onclick="downloadFile()">下载 Blob 文件</button><script>function downloadFile() {// 1. 创建 Blob 内容const text = "Hello, Blob!";const blob = new Blob([text], { type: 'text/plain' });// 2. 生成临时 URL 并下载const url = URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = 'example.txt';a.click();URL.revokeObjectURL(url);}</script>
</body>
</html>

5. File 和 FileReader

File作用:读取用户本地文件内容,继承自 Blob,表示用户本地文件(通过 <input type="file"> 获取),包含文件名、类型等元数据

FileReader作用:用于异步读取 Blob 或 File 内容为 ArrayBufferDataURL 或文本
优势:直接获取文件元数据,支持异步读取。
使用场景:文件上传、图片预览。

<!DOCTYPE html>
<html>
<body><input type="file" id="fileInput"><div id="output"></div><script>document.getElementById('fileInput').addEventListener('change', function(e) {const file = e.target.files[0];const reader = new FileReader();// 1. 读取为文本reader.readAsText(file);reader.onload = () => {document.getElementById('output').innerHTML = `<p>文件名: ${file.name}</p><p>大小: ${file.size} 字节</p><p>内容: ${reader.result}</p>`;};});</script>
</body>
</html>

6. ImageData 和 Canvas

作用:操作 Canvas 的像素数据。
优势:直接修改图像像素,实现实时效果。
使用场景:图像滤镜、实时视频处理。

<!DOCTYPE html>
<html>
<body><canvas id="canvas" width="200" height="200"></canvas><script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 1. 绘制原始图形ctx.fillStyle = 'red';ctx.fillRect(0, 0, 200, 200);// 2. 获取像素数据并反色const imageData = ctx.getImageData(0, 0, 200, 200);const data = imageData.data;for (let i = 0; i < data.length; i += 4) {data[i] = 255 - data[i];     // Rdata[i + 1] = 255 - data[i + 1]; // Gdata[i + 2] = 255 - data[i + 2]; // B}// 3. 写回修改后的像素ctx.putImageData(imageData, 0, 0);</script>
</body>
</html>

7. Streams API

作用:分块处理大型数据流,避免内存溢出。
优势:高效处理大文件,实时数据传输。
使用场景:视频流、大文件上传/下载。

<!DOCTYPE html>
<html>
<body><script>// 1. 创建一个简单的 ReadableStreamconst stream = new ReadableStream({start(controller) {controller.enqueue(new Uint8Array([72, 101, 108, 108, 111])); // "Hello"controller.close();}});// 2. 通过 Reader 读取数据块const reader = stream.getReader();reader.read().then(({ done, value }) => {if (!done) {console.log("流数据:", new TextDecoder().decode(value));}});</script>
</body>
</html>

8. WebAssembly

作用:运行高性能编译型代码(如 C/C++)。
优势:接近原生性能,适合计算密集型任务。
使用场景:游戏、音视频编码、加密算法。

<!DOCTYPE html>
<html>
<body><script>// 假设存在 add.wasm 文件,导出一个加法函数fetch('add.wasm').then(response => response.arrayBuffer()).then(buffer => WebAssembly.instantiate(buffer)).then(({ instance }) => {console.log("WASM 加法结果:", instance.exports.add(2, 3));});</script>
</body>
</html>

常用的二进制数据转换函数

1. 将 File 对象转换为 Blob 对象

/*** 将 File 对象转换为 Blob 对象(File 继承自 Blob,可直接切片)* @param {File} file - 用户上传的 File 对象* @returns {Blob} - 转换后的 Blob 对象*/
function fileToBlob(file) {// File 本身是 Blob 的子类,直接使用 slice 方法切割完整文件return file.slice(0, file.size, file.type);
}// 示例用法
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (e) => {const file = e.target.files[0];const blob = fileToBlob(file);console.log('File -> Blob:', blob);
});

2. 将 Blob 对象转换为 File 对象

/*** 将 Blob 转换为 File 对象(添加文件名和类型)* @param {Blob} blob - 需要转换的 Blob 对象* @param {string} fileName - 文件名(含扩展名,如 "image.jpg")* @param {string} [fileType] - 文件类型(如 "image/jpeg",默认使用 Blob 的 type)* @returns {File} - 转换后的 File 对象*/
function blobToFile(blob, fileName, fileType) {// 保留原始 Blob 的类型(若未指定 fileType)const type = fileType || blob.type;// 使用 File 构造函数创建对象(兼容性良好)return new File([blob], fileName, { type });
}// 示例用法
const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
const file = blobToFile(blob, 'example.txt');
console.log('Blob -> File:', file);

3. 将 Blob 转换为 ArrayBuffer

/*** 异步将 Blob 转换为 ArrayBuffer* @param {Blob} blob - 需要转换的 Blob 对象* @returns {Promise<ArrayBuffer>} - 返回 Promise 包含 ArrayBuffer*/
function blobToArrayBuffer(blob) {return new Promise((resolve, reject) => {// 使用 FileReader 读取 Blobconst reader = new FileReader();reader.onload = () => resolve(reader.result); // 读取完成返回 ArrayBufferreader.onerror = () => reject(reader.error);  // 处理错误reader.readAsArrayBuffer(blob); // 关键 API 调用});
}// 示例用法
const blob = new Blob(['Hello']);
blobToArrayBuffer(blob).then(buffer => {console.log('Blob -> ArrayBuffer:', buffer);
});

4. 将 ArrayBuffer 转换为 Blob

/*** 将 ArrayBuffer 转换为 Blob 对象* @param {ArrayBuffer} buffer - 需要转换的 ArrayBuffer* @param {string} [type] - Blob 的 MIME 类型(如 "image/png")* @returns {Blob} - 转换后的 Blob*/
function arrayBufferToBlob(buffer, type) {// 直接通过 Blob 构造函数转换return new Blob([buffer], { type: type || '' });
}// 示例用法
const buffer = new Uint8Array([72, 101, 108, 108, 111]).buffer;
const blob = arrayBufferToBlob(buffer, 'text/plain');
console.log('ArrayBuffer -> Blob:', blob);

5. 将 Blob 转换为 Base64 字符串

/*** 异步将 Blob 转换为 Base64 字符串* @param {Blob} blob - 需要转换的 Blob* @returns {Promise<string>} - 返回 Promise 包含 Base64 字符串*/
function blobToBase64(blob) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {// 去除 DataURL 前缀(如 "data:text/plain;base64,")const base64 = reader.result.split(',')[1];resolve(base64);};reader.onerror = () => reject(reader.error);reader.readAsDataURL(blob); // 读取为 DataURL});
}// 示例用法
const blob = new Blob(['Hello']);
blobToBase64(blob).then(base64 => {console.log('Blob -> Base64:', base64); // 输出 "SGVsbG8="
});

6. 将 Base64 字符串转换为 Blob

/*** 将 Base64 字符串转换为 Blob 对象* @param {string} base64 - Base64 字符串* @param {string} [type] - Blob 的 MIME 类型(如 "image/png")* @returns {Blob} - 转换后的 Blob*/
function base64ToBlob(base64, type) {// 将 Base64 转换为二进制字符串const byteString = atob(base64);// 创建 Uint8Array 视图const buffer = new Uint8Array(byteString.length);for (let i = 0; i < byteString.length; i++) {buffer[i] = byteString.charCodeAt(i);}// 生成 Blobreturn new Blob([buffer], { type: type || '' });
}// 示例用法
const base64 = 'SGVsbG8='; // "Hello" 的 Base64
const blob = base64ToBlob(base64, 'text/plain');
console.log('Base64 -> Blob:', blob);

7. 将 Blob 转换为 DataURL

/*** 异步将 Blob 转换为 DataURL(可直接用于 img.src)* @param {Blob} blob - 需要转换的 Blob* @returns {Promise<string>} - 返回 Promise 包含 DataURL*/
function blobToDataURL(blob) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => resolve(reader.result); // 直接返回完整 DataURLreader.onerror = () => reject(reader.error);reader.readAsDataURL(blob);});
}// 示例用法(图片预览)
const blob = new Blob([new Uint8Array([0x89, 0x50, 0x4E, 0x47])], { type: 'image/png' });
blobToDataURL(blob).then(dataURL => {console.log('Blob -> DataURL:', dataURL); // 输出 "data:image/png;base64,..."
});

8. 将 Blob 转换为 Object URL

/*** 将 Blob 转换为 Object URL(需手动释放内存)* @param {Blob} blob - 需要转换的 Blob* @returns {string} - Object URL(如 "blob:http://...")*/
function blobToObjectURL(blob) {// 使用 URL.createObjectURL 生成临时链接return URL.createObjectURL(blob);
}// 示例用法
const blob = new Blob(['Hello']);
const url = blobToObjectURL(blob);
console.log('Blob -> Object URL:', url);// 使用后需释放内存!
// URL.revokeObjectURL(url);

9. 将 Blob 转换为 Uint8Array

/*** 异步将 Blob 转换为 Uint8Array* @param {Blob} blob - 需要转换的 Blob* @returns {Promise<Uint8Array>} - 返回 Promise 包含 Uint8Array*/
function blobToUint8Array(blob) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {// 通过 ArrayBuffer 创建 Uint8Arrayconst buffer = reader.result;resolve(new Uint8Array(buffer));};reader.onerror = () => reject(reader.error);reader.readAsArrayBuffer(blob);});
}// 示例用法
const blob = new Blob(['Hello']);
blobToUint8Array(blob).then(uint8Array => {console.log('Blob -> Uint8Array:', uint8Array); // 输出 [72, 101, 108, 108, 111]
});

10. 将 Blob 转换为文本

/*** 异步将 Blob 转换为文本内容* @param {Blob} blob - 需要转换的 Blob* @param {string} [encoding] - 文本编码(默认 "utf-8")* @returns {Promise<string>} - 返回 Promise 包含文本内容*/
function blobToText(blob, encoding = 'utf-8') {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => resolve(reader.result);reader.onerror = () => reject(reader.error);reader.readAsText(blob, encoding); // 指定编码读取});
}// 示例用法
const blob = new Blob(['你好']);
blobToText(blob).then(text => {console.log('Blob -> Text:', text); // 输出 "你好"
});

11.使用总结

  • 通用逻辑:大部分转换依赖 FileReader 和 Blob 构造函数。

  • 关键点

    • FileReader 的 readAsXXX 方法决定读取格式。

    • Blob 的 type 属性影响生成文件的 MIME 类型。

    • Object URL 使用后需调用 URL.revokeObjectURL() 释放内存。

  • 错误处理:所有异步函数均返回 Promise,建议用 try/catch 包裹。

完整的图片上传案例

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>图片上传与居中全屏预览</title><style>/* 基础样式重置 */* {margin: 0;padding: 0;box-sizing: border-box;}/* 页面主体样式 */body {font-family: Arial, sans-serif;min-height: 100vh;background: #f5f5f5;display: flex;flex-direction: column;align-items: center;padding: 20px;}/* 上传容器样式 */.upload-container {background: white;padding: 30px;border-radius: 10px;box-shadow: 0 2px 10px rgba(0,0,0,0.1);margin-bottom: 20px;text-align: center;}/* 自定义上传按钮 */.custom-upload-btn {background: #2196F3;color: white;padding: 12px 24px;border-radius: 5px;cursor: pointer;transition: background 0.3s;display: inline-block;}.custom-upload-btn:hover {background: #1976D2;}/* 隐藏原生文件输入 */#fileInput {display: none;}/* 错误提示样式 */.error-message {color: #ff4444;margin-top: 10px;display: none;}/* 预览容器样式 */#previewContainer {max-width: 90%;margin: 20px 0;cursor: zoom-in;position: relative;display: none; /* 默认隐藏 */}/* 预览图片样式 */#previewImage {max-width: 100%;max-height: 70vh;border-radius: 8px;box-shadow: 0 4px 12px rgba(0,0,0,0.15);transition: transform 0.3s;}/* 全屏模式样式 */#previewContainer.fullscreen {position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;background: rgba(0, 0, 0, 0.9);z-index: 9999;cursor: zoom-out;display: flex !important; /* 强制覆盖默认样式 */align-items: center; /* 垂直居中 */justify-content: center; /* 水平居中 */}/* 全屏时图片样式 */#previewContainer.fullscreen #previewImage {max-width: 90vw;max-height: 90vh;object-fit: contain; /* 保持比例填充 */}</style>
</head>
<body>
<!-- 上传区域 -->
<div class="upload-container"><label class="custom-upload-btn" for="fileInput">📷 点击上传图片</label><input type="file" id="fileInput" accept="image/*"><div class="error-message" id="errorMessage">只能上传图片文件 (JPEG/PNG/GIF)</div>
</div><!-- 图片预览区域 -->
<div id="previewContainer"><img id="previewImage" alt="图片预览">
</div><script>// =====================// 元素获取// =====================const fileInput = document.getElementById('fileInput');const previewImage = document.getElementById('previewImage');const previewContainer = document.getElementById('previewContainer');const errorMessage = document.getElementById('errorMessage');// =====================// 文件上传处理// =====================fileInput.addEventListener('change', function(e) {const file = e.target.files[0];// 清除错误提示errorMessage.style.display = 'none';if (!file) return;// 验证文件类型if (!file.type.startsWith('image/')) {showError("文件类型错误,请选择图片");this.value = ''; // 清空选择return;}// 创建文件阅读器const reader = new FileReader();// 文件读取成功回调reader.onload = function(e) {previewImage.src = e.target.result;previewContainer.style.display = 'block'; // 显示预览容器};// 错误处理reader.onerror = function() {showError("文件读取失败");previewContainer.style.display = 'none';};// 开始读取文件reader.readAsDataURL(file);});// =====================// 全屏功能// =====================previewContainer.addEventListener('click', toggleFullscreen);// 全屏切换函数function toggleFullscreen() {if (document.fullscreenElement) {exitFullscreen();} else {enterFullscreen(previewContainer);}}// 进入全屏function enterFullscreen(element) {if (element.requestFullscreen) {element.requestFullscreen();} else if (element.mozRequestFullScreen) { // Firefoxelement.mozRequestFullScreen();} else if (element.webkitRequestFullscreen) { // Chrome/Safarielement.webkitRequestFullscreen();} else if (element.msRequestFullscreen) { // IE/Edgeelement.msRequestFullscreen();}// 添加全屏类名element.classList.add('fullscreen');}// 退出全屏function exitFullscreen() {if (document.exitFullscreen) {document.exitFullscreen();} else if (document.mozCancelFullScreen) { // Firefoxdocument.mozCancelFullScreen();} else if (document.webkitExitFullscreen) { // Chrome/Safaridocument.webkitExitFullscreen();} else if (document.msExitFullscreen) { // IE/Edgedocument.msExitFullscreen();}// 移除全屏类名previewContainer.classList.remove('fullscreen');}// 监听全屏状态变化document.addEventListener('fullscreenchange', () => {previewContainer.classList.toggle('fullscreen', !!document.fullscreenElement);});// =====================// 辅助函数// =====================function showError(message) {errorMessage.textContent = message;errorMessage.style.display = 'block';previewContainer.style.display = 'none';}
</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cacti 未经身份验证SQL注入漏洞

0x00 前言 Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具。 Cacti是通过 snmpget来获取数据&#xff0c;使用 RRDtool绘画图形&#xff0c;而且你完全可以不需要了解RRDtool复杂的参数。 0x01 漏洞描述 漏洞存在于从graph_view.php文件调用的growt…

使用国内源加速Qt在线安装

简介&#xff1a; 在线安装Qt时&#xff0c;会发现下载非常缓慢&#xff0c;可以用过使用国内镜像源来加速安装过程。 在线安装包的下载过程&#xff1a; 1&#xff0c;打开下载页面 https://www.qt.io/download-open-source 2&#xff0c;点击 Download the Qt online ins…

C#上位机RS485通信控制变频器

C#上位机使用Modbus RTU协议控制变频器 一、RTU报文格式示例 通信命令码&#xff1a; 03H:读从机参数 06H:写从机参数 10H:写多个参数上位机写单个寄存器&#xff1a;【从机地址】1字节【命令码】1字节【寄存器地址高-低】2字节【数据值高-低】2字节【CRC校验值低-高】…

OCC笔记:Brep格式

1. BREP格式简介 BREP格式是Open CASCADE内核&#xff08;OCCT&#xff09;的原生数据模型&#xff0c;直接描述几何体的边界表示&#xff08;面、边、顶点拓扑关系及几何参数&#xff09;。于OCCT内核的算法计算&#xff08;如布尔运算、曲面细分&#xff09;&#xff0c;存储…

Vue3进行工程化项目,保姆级教学(编译软件:vscode)大部分编译平台适用

目录 1. 创建vue工程 1.1 第一步 1.2 选择名称和工件 1.3 选择语言 1.4 自动下载js 1.5 运行vue工程 1.6 成功页面 2. 更改vue工程安装的位置 3. 更改运行工程方式 第一步 第二步 ​编辑 第三步 调试 ​编辑 运行项目 前面所学都是vue3的基础&#xff0c;为了简…

CSS常用选择器

CSS选择器用于选择HTML元素并为其应用样式。以下是CSS中最常用的选择器类型&#xff1a; 基本选择器 1.元素选择器 - 通过HTML标签名选择元素 p { color: blue; } 2.类选择器 - 通过class属性选择元素&#xff08;以.开头&#xff09; .warning { color: red; } 3.ID选择…

EmberGen导出序列图到UE5

选择Render节点 调整节点相关参数 然后选择一个目录 点击导出Export Now即可 材质用FlipBook 如果是特效就SubUV

EXCEL Python 实现绘制柱状线型组合图和树状图(包含数据透视表)

1、组合图、数据透视表 &#xff08;1&#xff09;数据预处理 知识点 日期函数 year() month()数据透视表操作 同比计算公式 环比计算公式 &#xff08;2&#xff09;excel 数据透视表插入组合图 a.2015~2017数据集处理方式&#xff1a; 操作&#xff1a; 结果 b.2020~20…

LabVIEW光谱检测系统

腔衰荡光谱技术&#xff08;CRDS&#xff09;凭借高精度和高灵敏度特性&#xff0c;成为微量气体浓度检测的常用方法&#xff0c;而准确获取衰荡时间是该技术应用的关键。基于LabVIEW平台设计腔衰荡信号在线处理系统&#xff0c;实现对衰荡信号的实时采集、平均、拟合、显示和保…

Flask快速入门和问答项目源码

Flask基础入门 源码&#xff1a; gitee&#xff1a;我爱白米饭/Flask问答项目 - 码云 目录 1.安装环境2.【debug、host、port】3.【路由params和query】4.【模板】5.【静态文件】6.【数据库连接】6.1.安装模块6.2.创建数据库并测试连接6.3.创建数据表6.4.ORM增删改查 6.5.ORM模…

flutter长列表 ListView、GridView、SingleChildScrollView、CustomScrollView区别

组件名称用途/适合场景是否懒加载支持列表结构用法复杂度SingleChildScrollView适用于内容数量不大、不重复的页面&#xff08;如表单、静态内容&#xff09;❌ 否❌ 否⭐⭐ListView适用于垂直方向的长列表&#xff0c;自动滚动&#xff1b;适合展示大量数据✅ 支持✅ 是⭐⭐Li…

鸿蒙OSUniApp 开发的一键分享功能#三方框架 #Uniapp

使用 UniApp 开发的一键分享功能 在移动应用开发中&#xff0c;分享功能几乎是必不可少的一环。一个好的分享体验不仅能带来更多用户&#xff0c;还能提升产品的曝光度。本文将详细讲解如何在 UniApp 框架下实现一个简单高效的一键分享功能&#xff0c;适配多个平台。 各平台分…

Vue-监听属性

监听属性 简单监听 点击切换名字&#xff0c;来回变更Tom/Jerry&#xff0c;输出 你好&#xff0c;Tom/Jerry 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>监听属性</title><!-- …

DeepSeek 赋能物联网:从连接到智能的跨越之路

目录 一、引言&#xff1a;物联网新时代的开启二、DeepSeek 技术揭秘2.1 DeepSeek 是什么2.2 DeepSeek 技术优势 三、DeepSeek 与物联网的融合之基3.1 物联网发展现状与挑战3.2 DeepSeek 带来的变革性突破 四、DeepSeek 在物联网的多元应用场景4.1 智慧电力&#xff1a;开启能源…

3.6/Q1,GBD数据库最新文章解读

文章题目&#xff1a;Global, regional, and national burden of geriatric depressive disorders in people aged 60 years and older: an analysis of the Global Burden of Disease Study 2021 DOI&#xff1a;10.1186/s12991-025-00560-2 中文标题&#xff1a;60 岁及以上人…

LVGL学习笔记

文章目录 一、 LVGL移植教程(GD32)一 并行驱动 LED二三一、 LVGL移植教程(GD32) 参考链接 1.GD32+LVGL移植教程(超详细)——基于GD32F303X系列MCU 一 并行驱动 LED 根据您提供的引脚信号(DCLK、DISP、HSYNC、VSYNC、DE),可以判断这是一款采用 TTL/Parallel RGB 接口…

软件架构之--论微服务的开发方法1

论微服务的开发方法1 摘要 2023年 2月,本人所在集团公司承接了长三角地区某省渔船图纸电子化审查系统项目开发,该项目旨在为长三角地区渔船建造设计院、以及渔船图纸审查机构提供一个便捷的渔船图纸电子化审查服务平台。在此项目中,我作为项目组成员参与项目的建设工作,并…

如何在终端/命令行中把PDF的每一页转换成图片(PNG)

今天被对象安排了一个任务&#xff1a; 之前自己其实也有这个需要&#xff0c;但是吧&#xff0c;我懒&#xff1a;量少拖拽&#xff0c;量大就放弃。但这次躲不过去了&#xff0c;所以研究了一下有什么工具可以做到这个需求。 本文记录我这次发现的使用 XpdfReader 的方法。…

mac安装cast

背景 pycharm本地运行脚本时提示cast没有安装 问题原因 脚本尝试调用cast命令&#xff08;以太坊开发工具foundry中的子命令&#xff09;&#xff0c;但您的系统未安装该工具。 从日志可见&#xff0c;错误发生在通过sysutil.py执行shell命令时。 解决方案 方法1&#xf…

【搭建Node-RED + MQTT Broker实现AI大模型交互】

搭建Node-RED MQTT Broker实现AI大模型交互 搭建Node-RED MQTT Broker实现AI大模型交互一、系统架构二、环境准备与安装1. 安装Node.js2. 安装Mosquitto MQTT Broker3. 配置Mosquitto4. 安装Node-RED5. 配置Node-RED监听所有网络接口6. 启动Node-RED 三、Node-RED流程配置1. …