WPF 中使用 ZXing.Net 实现二维码生成与识别实战指南
简介面向C# WPF开发者的二维码生成与识别示例工程基于zxing.netzxing.dll完成QR码编码并引入EPFMediaKit.dll辅助摄像头/图像处理解决桌面应用快速集成二维码交互的需求。压缩包体积22.48MB共148个文件以dll依赖库、cs源码、xaml界面布局、sln工程文件为主附带pdb调试符号、xml注释、config配置与packages.config依赖声明目录结构完整可直接在Visual Studio中打开运行。已有1002人学习下载。示例不仅演示了BarcodeWriter创建二维码并绑定Image控件还给出了从图像或摄像头读取识别码的参考思路通过阅读MainWindow相关代码和xaml布局可快速掌握WPF下的UI绑定、按钮交互与二维码模块集成方式并借鉴项目中的错误处理与工程组织方法便于迁移到自己的应用中。1. 这个 demo 解决什么问题C# WPF 桌面端接入二维码功能最大的障碍往往不是业务逻辑而是 ZXing 与 WPF 图像体系之间的适配。ZXing 的原始 API 面向 Java 和 WinForms 设计到了 WPF 里输出要对齐 WriteableBitmap输入要做 BitmapSource 到 System.Drawing.Bitmap 的像素拷贝每一步都有版本兼容的坑。这个 demo 把二维码的生成和识别两条链路完整跑通生成侧配置 ZXing.Net 的 BarcodeWriter输出 WriteableBitmap 直接绑定界面上的 Image识别侧支持本地图片和剪贴板两个入口解码后返回文本内容与定位点坐标。适合做桌面工具、需要给业务单据加二维码标签或者做扫码录入的开发者直接照抄关键方法就能落地不用再花一个下午去翻 ZXing 的英文文档。2. 技术选型与项目结构ZXing.Net 在 WPF 中的落地姿势2.1 为什么选 ZXing.Net 而不是其他库.NET 生态里二维码库的现状是这样的QRCoder 简洁但只管生成、不支持识别做“扫码录入”这类功能还得另找解码方案ThoughtWorks.QRCode 是前些年的老库到今天已经没有维护在 .NET 6/8 上编译横竖都是问题。ZXing.Net 是 ZXing 的 .NET 移植版NuGet 包名很直白搜 ZXing.Net 就能拿到。它从生成到识别都有统一的抽象不只支持 QRCode还覆盖 Code128、EAN-13、DataMatrix 等几十种条码格式同一个 BarcodeFormat 枚举在生成和解码两侧共用。选型的时候我一般会先确认一件事这个库在 WPF 下有没有现成的渲染器。ZXing.Net 官方带了一个 WriteableBitmapRenderer所以 BarcodeWriter 可以直接泛型实例化为 BarcodeWriter 输出就是 WPF 原生位图类型不需要自己再去把 Bitmap 转一遍 BitmapSource。这个 demo 虽然只用了 QR_CODE 一种格式但枚举的扩展点留在那里后续想做商品条码扫描工具也不用换库。2.2 项目目录结构与分层拆开 demo 源码后合理的组织方式是这样的界面事件只做编排把 ZXing 相关的初始化、参数配置全部收进 Service 层避免 MainWindow.xaml.cs 里堆一两百行库代码。目录结构如下QrCodeDemo/ └─ QrCodeDemo/ ├─ App.xaml 应用入口统一资源与窗口配置 ├─ MainWindow.xaml 主窗体左侧生成区 右侧识别区 ├─ MainWindow.xaml.cs 事件处理只负责调用 Service、刷新界面 ├─ Services/ │ ├─ QrCodeEncoder.cs 生成封装BarcodeWriter 与二维码参数集中管理 │ └─ QrCodeDecoder.cs 识别封装统一文件/剪贴板解码入口 ├─ Extensions/ │ └─ BitmapConverter.cs BitmapSource 与 System.Drawing.Bitmap 互转 └─ Models/ └─ QrDecodeResult.cs 识别结果模型含文本、格式、定位点这个分层的价值在你二次开发的时候才会体现出来。比如你要加一个“批量生成工单二维码”的功能只需要在某个 ViewModel 里循环调用 QrCodeEncoder.Generate不需要再碰任何 ZXing 代码要换解码策略也只需要改 QrCodeDecoder 一个类。demo 规模小不强上 MVVM 框架但至少做到“界面不直接依赖第三方库”这是我拿到源码后第一个会检查的点。2.3 主窗体布局与两条调用链路主窗体是标准的左右分栏左侧输入内容生成二维码右侧打开图片或读剪贴板做识别。XAML 里关键的几个控件如下Grid Margin12 Grid.ColumnDefinitions ColumnDefinition Width*/ ColumnDefinition Width*/ /Grid.ColumnDefinitions GroupBox Header二维码生成 Padding8 StackPanel TextBox x:NametxtContent Height80 TextWrappingWrap AcceptsReturnTrue VerticalScrollBarVisibilityAuto/ Button x:NamebtnGenerate Content生成 ClickBtnGenerate_Click HorizontalAlignmentLeft Padding16,6 Margin0,8,0,0/ Image x:NameimgQrCode Width240 Height240 StretchUniform RenderOptions.BitmapScalingModeNearestNeighbor Margin0,12,0,0/ Button x:NamebtnSave Content保存 PNG ClickBtnSave_Click HorizontalAlignmentLeft Padding16,6 Margin0,8,0,0/ /StackPanel /GroupBox GroupBox Header二维码识别 Grid.Column1 Padding8 StackPanel Button x:NamebtnOpenImage Content打开图片识别 ClickBtnOpenImage_Click HorizontalAlignmentLeft Padding16,6/ Button x:NamebtnDecodeClipboard Content从剪贴板识别 ClickBtnDecodeClipboard_Click HorizontalAlignmentLeft Padding16,6 Margin0,8,0,0/ TextBox x:NametxtResult Height80 TextWrappingWrap VerticalScrollBarVisibilityAuto IsReadOnlyTrue/ /StackPanel /GroupBox /Grid生成链路是点击生成按钮 → QrCodeEncoder.Generate 返回 WriteableBitmap → 赋值给 imgQrCode.Source识别链路是打开图片文件 → BitmapImage 加载 → 转成 System.Drawing.Bitmap → BarcodeReader.Decode → 结果回填到 txtResult。两条链路都不经过磁盘中间文件数据全在内存里流动这也是这个 demo 比网上那些“生成图片保存到临时目录再读回来识别”的示例干净的地方。3. 生成模块拆解从内容字符串到可保存的二维码图片3.1 QrCodeEncoder 的封装与关键参数生成侧的入口是 Services/QrCodeEncoder.cs核心代码不长但每一行参数都有自己的讲究// Services/QrCodeEncoder.cs using ZXing; using ZXing.QrCode; using System.Windows.Media.Imaging; public class QrCodeEncoder { private readonly BarcodeWriterWriteableBitmap _writer; public QrCodeEncoder() { _writer new BarcodeWriterWriteableBitmap { Format BarcodeFormat.QR_CODE, Options new QrCodeEncodingOptions { Width 360, Height 360, Margin 1, CharacterSet UTF-8, ErrorCorrection ZXing.QrCode.Internal.ErrorCorrectionLevel.M, QrVersion 0 } }; } public WriteableBitmap Generate(string content) { if (string.IsNullOrWhiteSpace(content)) throw new ArgumentException(二维码内容不能为空, nameof(content)); return _writer.Write(content); } }这里最关键的是泛型参数 WriteableBitmap它决定了 ZXing 输出哪种位图。BarcodeWriter 会根据泛型类型自动选择对应的渲染器在 WPF 项目里用它输出 WriteableBitmap可以直接赋给 Image.Source不需要额外的类型转换。参数层面的几个取值我整理成一张表方便你对照调整参数作用demo 取值什么时候需要改Width / Height输出位图的像素尺寸360需要打印大标签时按比例加大比如 600Margin静区宽度单位是“模块”而不是像素1要贴在包装上时建议加到 2防止裁切CharacterSet内容编码方式UTF-8内容只含纯 ASCII 时无所谓含中文必须为 UTF-8ErrorCorrection容错等级 L/M/Q/HM打印在易磨损介质上时改成 HQrVersion指定二维码版本0 表示自动选择0一般不动交给库自动算ErrorCorrection 是容错等级从低到高是 L、M、Q、H对应约 7%、15%、25%、30% 的损毁容忍度。等级越高二维码图案越密但抗污抗折能力越强。demo 里取 M 是日常屏幕显示和普通打印的平衡点如果扫码场景是包装箱、标签纸这种容易脏的环境直接改 H。3.2 生成按钮的调用链与界面绑定按钮事件里的逻辑很薄就是把文本交给 Encoder把返回的 WriteableBitmap 丢给 Imageprivate void BtnGenerate_Click(object sender, RoutedEventArgs e) { try { var qr _encoder.Generate(txtContent.Text); imgQrCode.Source qr; btnSave.IsEnabled true; } catch (ArgumentException ex) { MessageBox.Show(ex.Message, 输入检查); } catch (Exception ex) { MessageBox.Show($生成失败{ex.Message}, 提示); } }WriteableBitmap 继承自 BitmapSource所以它本身就是 WPF 图像链路上的一等公民赋给 Image.Source 不需要再转成 BitmapImage。有一点值得注意WriteableBitmap 默认是“可写”状态所以除非你要跨线程共享这个位图否则不要调用 Freeze()一旦冻结后续想再改像素就会抛 InvalidOperationException。这里我把异常分开了两层处理ArgumentException 是业务校验其他异常归为系统异常。实际项目里不要直接吞掉异常至少要先记日志再弹窗方便用户把错误信息带给你。3.3 保存为 PNG 文件的实现生成二维码之后下一步通常是落盘WPF 自带的 PngBitmapEncoder 就够了不用引入 System.Drawing 的 Save 方法private void BtnSave_Click(object sender, RoutedEventArgs e) { var dlg new SaveFileDialog { Filter PNG 图片|*.png, FileName $QR_{DateTime.Now:yyyyMMddHHmmss}.png }; if (dlg.ShowDialog() ! true) return; var encoder new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create((BitmapSource)imgQrCode.Source)); using (var fs new FileStream(dlg.FileName, FileMode.Create)) { encoder.Save(fs); } }这里选择 PNG 而不是 JPEG是因为二维码是二值图像PNG 的无损压缩能完整保留模块边缘JPEG 的压缩反而会在黑白边界上产生振铃效应影响扫码枪识别。从 Image.Source 拿位图而不是自己再存一份 WriteableBitmap是为了保证保存的图和用户看到的是同一份数据避免“预览正常、存下来花掉”这种诡异问题。4. 识别模块拆解从图片文件到识别结果的完整链路4.1 绕不开的类型转换BitmapSource 到 System.Drawing.Bitmap识别侧第一道坎是类型转换。ZXing.Net 的 BarcodeReader.Decode 方法接受的是 System.Drawing.Bitmap、RGBLuminanceSource 或原始像素数组它不认识 WPF 的 BitmapSource。所以在 WPF 项目里必须先做一个像素拷贝把 BitmapSource 的像素拷进一个 System.Drawing.Bitmap 的缓冲区。这里封装了一个扩展方法// Extensions/BitmapConverter.cs using System.Drawing; using System.Drawing.Imaging; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; public static class BitmapConverter { public static Bitmap ToGdiBitmap(this BitmapSource source) { // 统一转成 Bgra32保证后面按 4 字节/像素计算 stride 不会出错 var converted new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0); int width converted.PixelWidth; int height converted.PixelHeight; int stride width * 4; var bmp new Bitmap(width, height, PixelFormat.Format32bppArgb); var data bmp.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); converted.CopyPixels( new Int32Rect(0, 0, width, height), data.Scan0, height * stride, stride); bmp.UnlockBits(data); return bmp; } }逻辑拆开讲三步先通过 FormatConvertedBitmap 把任意来源的 BitmapSource 统一转成 Bgra32这一步解决了 InteropBitmap、灰度图、不同 DPI 带来的像素格式差异然后 new 一个 Format32bppArgb 的 Bitmap它的内部像素布局和 Bgra32 完全对应最后用 LockBits 锁定内存区把 data.Scan0 这个首地址交给 CopyPixelsWPF 的像素缓冲就被直接写进 Bitmap 的内存里。UnlockBits 必须在 CopyPixels 之后调用否则数据没有真正落地。这段代码里最值得留意的是 stride 的计算。stride 是 bitmap 每行像素占用的字节数Bgra32 每像素固定 4 字节所以 width 乘 4 就是 stride。如果你在网上抄到“height 乘 data.Stride”的写法那要求源图像的 stride 和目标完全一致一旦源是灰度图就会踩坑。统一先转 Bgra32 是最稳的路径。4.2 文件识别的完整流程文件识别流程要处理两个问题一是图片加载不能锁文件二是解码参数要配置到适合二维码识别的状态。完整实现如下// Services/QrCodeDecoder.cs using ZXing; using ZXing.Common; public class QrCodeDecoder { public QrDecodeResult DecodeFile(string filePath) { var bitmapImage new BitmapImage(); using (var fs new FileStream(filePath, FileMode.Open, FileAccess.Read)) { bitmapImage.BeginInit(); bitmapImage.CacheOption BitmapCacheOption.OnLoad; bitmapImage.StreamSource fs; bitmapImage.EndInit(); } // 走到这里文件流已经释放图片数据完整驻留内存 using (var bmp bitmapImage.ToGdiBitmap()) { return DecodeCore(bmp); } } private QrDecodeResult DecodeCore(Bitmap bmp) { var reader new BarcodeReader { Options new DecodingOptions { TryHarder true, PossibleFormats new ListBarcodeFormat { BarcodeFormat.QR_CODE } } }; var result reader.Decode(bmp); if (result null) return null; return new QrDecodeResult { Text result.Text, FormatName result.BarcodeFormat.ToString(), Points result.ResultPoints }; } }BitmapImage 加载这段有两个细节值得展开。CacheOption 设置为 OnLoad意思是 EndInit 时立刻把图像完全解码进内存而不是等 Image 控件渲染时才读取。加上 StreamSource 直接接 FileStreamEndInit 之后 using 块退出文件流被释放文件句柄也就释放了。如果你用 UriSource 加载Windows 下会持有文件锁识别完想删图或改名就会报“文件被占用”。DecodingOptions 里的 TryHarder 是一个很有用的选项。它的作用是让解码器在第一次扫描失败后继续尝试更多亮度阶梯和旋转角度对倾斜、偏暗、反光的图片友好很多。代价是耗时大约翻倍单张图几十毫秒到一两百毫秒不等桌面交互场景完全可以接受。PossibleFormats 限制成 QR_CODE 后解码器不需要去匹配条形码的形态误识别率会低不少速度也更快。4.3 剪贴板图片识别剪贴板识别是桌面工具里被用得很多的功能用户截图后直接点按钮就能读出二维码不用先存文件再打开。实现上要处理剪贴板返回的 InteropBitmappublic QrDecodeResult DecodeFromClipboard() { if (!Clipboard.ContainsImage()) return null; try { var source Clipboard.GetImage(); // InteropBitmap 的像素格式不稳定统一走 Bgra32 再解码 var converted new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0); using (var bmp converted.ToGdiBitmap()) { return DecodeCore(bmp); } } catch (Exception ex) { Debug.WriteLine($剪贴板取图失败{ex}); return null; } }Clipboard.GetImage() 返回的是一个特殊类型它在内部持有剪贴板数据的引用像素格式和 DPI 都取决于截图来源不稳定。直接拿它去做像素拷贝轻则 stride 不匹配导致图像错位重则 CopyPixels 抛“参数无效”。所以在进 ToGdiBitmap 之前先 FormatConvertedBitmap 统一转一遍后面所有逻辑就和文件识别路径完全一致了。另外注意一点如果剪贴板里的图是一张 4K 截图转换成 Bitmap 再解码的耗时可能接近一秒。这个环节不该放 UI 线程上裸跑。demo 里为了保持简单直接同步调用你如果要做成产品至少包一层 Task.Run解码完成再通过 Dispatcher 回到 UI 线程更新文本框。5. 常见问题排查WPF 集成 ZXing 时最容易踩的坑5.1 Decode 参数类型不匹配编译直接报错现象把 WPF 的 BitmapImage 直接传给 reader.Decode(bitmapImage)编辑器直接标红提示没有匹配的重载。原因ZXing.Net 的 BarcodeReader 只吃 System.Drawing.Bitmap、LuminanceSource 或原始像素数组不认 BitmapSource 家族。这是两条图像技术栈一个是 WPF 的 Freezable 体系一个是 GDI 的非托管包装二者没有隐式转换。解决写一个 BitmapConverter 扩展方法做像素拷贝如 4.1 节所示。注意 System.Drawing.Common 在 .NET 5 下要显式添加 NuGet 包引用WPF Windows 桌面项目可以正常用但不要忘记在 csproj 里加 PackageReference。5.2 识别一次后图片文件被占用现象程序打开某张图片识别成功之后在资源管理器里删除或重命名该文件弹出“文件正在被另一个进程使用”。原因BitmapImage 的默认 CacheOption 是 OnDemand图像数据延迟加载底层 FileStream 一直被 BitmapImage 持有不释放。如果用的是 Bitmap 构造函数直接读文件也会因为流没释放导致句柄卡住。解决用 FileStream 显式打开文件设置 CacheOption BitmapCacheOption.OnLoadEndInit 后再退出 using 块。OnLoad 的语义就是图片数据立即解码进内存流用完就可以扔。5.3 中文内容生成后扫出来乱码现象二维码内容里带中文比如“工单A001”用手机扫出来是“G-CON…”或者直接空缺一块。原因ZXing 编码字符串时默认走的不是 UTF-8而是按系统区域的默认编码。解码端手机普遍按 UTF-8 解读字节流两边不一致就出现乱码或空字符。解决生成时在 QrCodeEncodingOptions 里显式设置 CharacterSet UTF-8保证写入二维码的字节流用的是 UTF-8。这里不用自己去 UTF8.GetBytesZXing 内部会按 CharacterSet 处理字符串手动转字节反而会破坏输入的字符串类型约束。5.4 打印后手机扫不出来现象屏幕显示识别正常打印到标签纸上一扫就失败用微信和扫码枪都试过。原因最常见的两类一是静区被裁掉Margin 设为 0 时二维码模块贴边裁切线或折痕直接吃掉定位角二是容错等级太低打印墨迹扩散导致相邻模块粘连识别器无法区分黑白边界。解决Margin 至少设 1推荐 2ErrorCorrection 从 M 改成 H。注意 Margin 单位是模块360 像素的图 Margin2 大约在四边各留约 25 像素空白。改完重新生成、重新打印识别率提升非常明显。5.5 小尺寸二维码放大显示边缘发虚现象生成 120×120 的二维码界面 Image 控件按 240 显示边缘全是灰阶过渡扫码偶尔失败。原因WPF 默认用线性插值对位图做缩放二维码是纯黑白二值图线性插值会在黑白边界产生灰色像素破坏了二维码的锐利边缘。解决要么直接把 Width / Height 设成最终显示尺寸从源头避免放大要么给 Image 设置 RenderOptions.BitmapScalingModeNearestNeighbor让 WPF 用最近邻采样保持像素边缘的清晰度。打印场景下建议用第一种生成多大就是多大不做任何缩放。6. 二次开发思路把 demo 改造成批量识别工具6.1 批量识别文件夹中的图片demo 的识别入口是单张图片改成批量识别只需要在 QrCodeDecoder 外面套一层循环。核心代码可以这样组织public async Task BatchDecodeAsync(IEnumerablestring files, IProgressBatchProgress progress) { await Task.Run(() { var decoder new QrCodeDecoder(); foreach (var file in files) { var result decoder.DecodeFile(file); progress.Report(new BatchProgress { FilePath file, Text result?.Text, Succeeded result ! null }); } }); }批量场景最大的坑是 UI 卡死。解码单张图几十毫秒一百张图就是好几秒放在 UI 线程上会直接失去响应。用 Task.Run 把解码放到线程池再通过 IProgress 回传进度界面用 DataGrid 或者 ListBox 绑定结果列表每处理完一张刷新一行。如果一次要处理上万张图还需要考虑内存每张图用完后立即释放DecodeFile 里的 using 已经保证了这一点。拿到这份 demo 源码后第一件事不是打开工程而是先找到 src 目录下 csproj 里的 PackageReference确认 ZXing.Net 的版本再去看 QrCodeEncoder 和 QrCodeDecoder 两个类把 3.1 和 4.2 的参数表打印出来贴显示器旁边后面改参数随时对照。6.2 三个值得继续扩展的方向第一个方向是摄像头实时识别。用 MediaCapture 或者 AForge.NET 抓帧每一帧转成 BitmapSource再走 ToGdiBitmap DecodeCore 这条链路。注意控制帧率ZXing 单帧解码耗时 30 到 200 毫秒实时识别建议用独立线程解码一帧的同时丢弃后续帧避免队列堆积。第二个方向是带 Logo 的二维码。生成后把 BitmapSource 转成 System.Drawing.Bitmap用 Graphics 把 Logo 画到中心区域。Logo 面积不要超过整个二维码的四分之一容错等级必须调到 H不然遮挡的模块会超过纠错能力扫码直接失败。第三个方向是失败重试机制。Decode 返回 null 时把图像旋转 90 度和 180 度再各试一次手机上拍摄的二维码经常带角度靠 TryHarder 不一定能拉回来。这是一个很有效的补丁批量识别的成功率能提升不少。以前我在某个桌面项目里为了能删掉识别过的图片把缓存目录整体挪到了临时文件夹治标不治本后来把 BitmapCacheOption 的原理搞明白才发现文件句柄问题从源头就该用 OnLoad 解决。从那以后我每次在 WPF 里碰图像 I/O都强制走一遍“FileStream OnLoad → 用完即释放 → 识别完再解绑”这个流程省下的调试时间远比多敲的几行代码多。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

从pom到yml:Maven资源过滤实现版本号与构建时间自动注入

从pom到yml:Maven资源过滤实现版本号与构建时间自动注入

前两天搭新服务时遇到一个需求:版本号、构建时间要直接出现在接口里,方便运维确认线上跑的是不是最新包。群里很快有人提议,在application.yml里写死一个版本号,改版本的时候同步改一次。我当场反对:版本号在pom里已经…

2026/10/18 21:05:34 阅读更多 →
ITextRenderer实战:Java后端HTML转PDF的关键配置与批量生成指南

ITextRenderer实战:Java后端HTML转PDF的关键配置与批量生成指南

简介:面向需要在 Java 项目中把 HTML 模板转换为 PDF 文件的开发者,提供一套可直接参考使用的工具类。该类基于 ITextRenderer(Flying Saucer)编写,覆盖 HTML 内容加载、CSS 样式布局、PDF 渲染输出等核心环节&#xf…

2026/10/18 21:05:34 阅读更多 →
工业HMI三级跳:从显示面板到智慧大脑的进化之路

工业HMI三级跳:从显示面板到智慧大脑的进化之路

工业HMI从“傻白甜”进化到“智慧大脑”,三级跳这个说法在自动化圈子里越来越有共鸣。我在产线上和设备打交道十几年,最大的感受是:人机界面变了,车间管理方式才会跟着变。这块不显眼的面板,过去是机器的“脸面”&…

2026/10/18 21:05:34 阅读更多 →

最新新闻

Linux基础指令实战:从文件操作到权限管理

Linux基础指令实战:从文件操作到权限管理

1. 内容整体设计与思路拆解1.1 为什么Linux基础指令是绕不开的第一关做了这么多年开发和运维,我见过不少这样的同事:项目代码写得挺顺,一上服务器就发懵,连日志文件在哪儿都找不到,最后只能求助旁边的人。说句实在话&a…

2026/10/18 22:03:21 阅读更多 →
印刷报价系统从设计到落地:三张主表、计价公式与避坑指南

印刷报价系统从设计到落地:三张主表、计价公式与避坑指南

简介:面向印刷行业中小企业的报价管理软件资源,覆盖印刷业务核心流程,包括报价计算、客户档案、产品目录、材料库存、设备维护及数据维护等功能。系统内置印刷工艺、纸张类型、印刷数量等常用参数,支持特殊订单自定义报价&#xf…

2026/10/18 22:03:21 阅读更多 →
10%标注媲美全监督:BCSI半监督学习实战解析

10%标注媲美全监督:BCSI半监督学习实战解析

过去几个月,我一直在做半监督方向的东西,看到AAAI 2026这篇标题为“10%标注数据媲美全监督”的论文时,第一反应是不太信。圈子里每年都有类似的狠话,但真正把效果跑出来的没几个。结果我按它的思路在模拟项目和两个开源数据集上复…

2026/10/18 22:03:21 阅读更多 →
Select模型详解:用C++写一个多客户端聊天服务器

Select模型详解:用C++写一个多客户端聊天服务器

先别急着上完成端口。如果你只是写过阻塞式Socket收发,第一次面对“同时处理一堆客户端连接”这个问题时,Select模型是你绕不过去的第一道门。网上讲五种I/O模型的文章不少,但大多数要么直接甩一段代码,要么把原理讲得像天书&…

2026/10/18 22:03:21 阅读更多 →
Claude Code 零基础入门:工具使用全指南(含 TaoToken 统一 Key 配置)

Claude Code 零基础入门:工具使用全指南(含 TaoToken 统一 Key 配置)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 22:03:21 阅读更多 →
ETH私钥碰撞器v1.2:暴力破解概率与弱私钥自检实践

ETH私钥碰撞器v1.2:暴力破解概率与弱私钥自检实践

简介:ETH私钥碰撞器v1.2是一款面向区块链安全研究与私钥恢复场景的实用工具,适合具备一定密码学基础的开发者、安全测试人员和链上数据分析人员。资源包共包含6个文件,主要文件类型为txt、exe和js;其中txt文档给出了使用说明与参数…

2026/10/18 22:02:21 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →