Flutter在OpenHarmony上的短信二维码生成实战
周末接到一个需求在OpenHarmony系统的设备上跑一个二维码工具类App既要能扫码又要能生成短信二维码方便别人扫一下直接跳转发短信。团队里已有的技术栈是FlutterApp本身不大不想为了这一个功能单独拉一套ArkTS开发人力。于是就有了这篇文章——记录整个Flutter for OpenHarmony实战过程重点是短信二维码生成这块的实现细节。这个项目最有意思的点在于Flutter在OpenHarmony上的适配已经走过了从实验室到可落地的阶段但网上能搜到的完整实战案例依然不多。尤其是生成短信二维码这种需求普通教程只会教你调一个二维码库根本不会告诉你短信二维码的格式协议是什么、怎么编码才能被各家扫码App正确识别、以及如何在OpenHarmony环境下处理中英文混排和特殊字符。这篇文章会把完整链路讲透适合两类人看一类是想在OpenHarmony上复用Flutter代码的跨端开发者另一类是单纯想把扫码生成这两个功能做扎实的移动端工程师。1. 为什么用Flutter跑OpenHarmony而不是直接用ArkTS重写先说选型。OpenHarmony原生推荐的是ArkTS ArkUI但现实问题是如果你的核心业务逻辑已经用Flutter写完并且要同时覆盖Android、iOS、OpenHarmony三端重写一遍ArkTS的成本很高后续维护也是两套人马。Flutter官方在2023年下半年开始合入OpenHarmony适配分支到目前已经有不少API可以在鸿蒙设备上跑通。我的判断是工具型App、内部效率工具、演示Demo这类轻量场景Flutter for OpenHarmony完全够用如果是做系统级深度定制的商业App那还是要老老实实评估ArkTS。这里要区分两个概念避免踩坑。Flutter官方主干版本stable默认不支持OpenHarmony构建你需要使用OpenHarmony分支的Flutter SDK通常是通过clone特定仓库、切换对应分支获得。社区里也有厂商维护的发行版我个人建议优先看flutter_flutter仓库的OpenHarmony分支以及配套的flutter_engine、flutter_plugins版本对齐关系要严格按说明来不能混用。实际分配给我的任务划分是这样扫码页面调用相机实时识别画面中的二维码短信二维码生成用户在输入框填手机号和短信内容点生成按钮得到一张二维码图片结果保存二维码图片保存到相册或者直接展示给另一个手机扫码整个App不需要网络不依赖后端这就非常适合Flutter的本地渲染能力。2. 环境搭建OpenHarmony版Flutter SDK的完整配置过程Flutter for OpenHarmony的环境搭建跟普通Flutter开发有几点关键差异逐一说明。2.1 工具链版本与对齐关系我当时使用的配置如下供参考注意版本随社区迭代可能更新以官方文档为准组件版本/分支操作系统Windows 11 / Ubuntu 22.04 均可Flutter SDKflutter_flutter的OpenHarmony适配分支DevEco Studio4.0 Release及以上OpenHarmony SDKAPI 9/10/11 均可需要与DevEco匹配ohpm鸿蒙包管理器用于安装原生依赖Node.js16.19.0以上这里最容易翻车的就是Flutter SDK分支和DevEco Studio版本对不上。我一开始直接clone了master分支结果构建时报了一堆API不存在后来发现要切到对应的tag上例如某些适配版本只支持指定版本的OpenHarmony SDK。如果你的项目不是从零开始建议先跑一个空项目验证环境不要上来就编译业务代码。2.2 项目创建与目录结构创建一个OpenHarmony Flutter的工程跟纯Flutter工程不一样。它本质上是一个OpenHarmony工程Flutter代码作为其中的模块存在。流程大致是用DevEco Studio创建一个标准的OpenHarmony工程将flutter模块通过依赖方式引入项目根目录 ├── AppScope ├── entry # OpenHarmony原生入口模块 │ ├── src/main │ │ ├── ets # ArkTS代码负责原生桥接 │ │ └── resources # 资源文件 ├── flutter_module # Flutter业务模块 │ ├── lib │ ├── pubspec.yaml │ └── .flutter-plugins-dependencies └── oh-package.json5 # 鸿蒙侧依赖配置这个结构意味着入口是OpenHarmony的Ability类似Android的Activity它加载一个Flutter容器来展示Flutter页面。也就是说Flutter代码并不是独立App而是运行在OpenHarmony应用内的一个渲染引擎。理解了这个模型后面调试各种桥接问题都会顺畅很多。2.3 环境变量与本地配置我踩过的坑是Java环境和ohpm环境变量。DevEco Studio自带的JBR版本如果跟命令行用的JDK不一致Gradle构建会莫名其妙挂掉。建议显式设置export JAVA_HOME/path/to/your/jdk export PATH$JAVA_HOME/bin:$PATH export HOS_SDK_HOME/path/to/OpenHarmony/SDK export OHPM_HOME/path/to/ohpm另外OpenHarmony工程的构建脚本需要签名配置调试模式下也需要。我一开始漏掉了签名一直报错后来在build-profile.json5里补上了调试签名才跑起来。签名文件可以用DevEco的自动生成功能。3. 扫码页面实现Camera在OpenHarmony上的两种调用方式扫码是二维码工具的基础功能。在OpenHarmony上调用摄像头Flutter侧没有一揽子现成方案我梳理了两条路线。3.1 路线一Platform Channel调用鸿蒙原生Scan KitOpenHarmony官方提供扫码服务Scan Kit封装了相机扫码能力支持二维码、条码的识别。这种方式的好处是识别率高、自动对焦、支持暗光环境补光。代价是需要在ArkTS侧写不少桥接代码。核心步骤在ArkTS侧封装一个扫码组件调用系统的scan能力通过MethodChannel把识别结果回调给Flutter侧MethodChannel与Platform Channel在OpenHarmony上的命名方式与Android一致 dart // Flutter侧 const MethodChannel _channel MethodChannel(com.example.scanner/qr_scan); String? result await _channel.invokeMethod(scanWithCamera);但这条路有个问题相机预览界面是原生控件Flutter这边只能等最终扫描结果无法自定义扫码框、灯光按钮等UI细节。如果你的需求就是打开相机扫一下拿结果用原生Scan Kit最快最稳。3.2 路线二camera插件采集帧 Dart侧解码我最终选择的是这套方案Flutter官方维护的camera插件在OpenHarmony上可以用先拿到相机预览流然后控制它拍照或采集帧再用解码算法识别二维码。这个方案能保持UI在Flutter侧完全可控扫码框动画、闪光灯按钮、相册选择都能做成一套代码。代价是帧解码的耗时需要自己优化。Dart侧的二维码解码我用的是以为基础移植的纯Dart实现。不过要说明一点纯Dart解码库在OpenHarmony上跑性能比原生扫码差一些尤其是高分辨率相机帧解码耗时可能到几百毫秒。优化手段是把相机预览分辨率降到1280x720甚至更低同时把帧转为灰度图再送解码器识别速度能快很多。3.3 权限申请是第一个拦路虎OpenHarmony的相机权限跟Android类似但是API名字不同需要在module.json5里声明{ requestPermissions: [ { name: ohos.permission.CAMERA, reason: 需要使用相机扫描二维码, usedScene: { abilities: [ EntryAbility ] } } ] }注意只声明了静态权限还不够运行时还需要动态申请。鸿蒙的权限弹窗是系统控制的申请路径在Flutter侧无法直接调用需要走Platform Channel让原生Ability触发requestPermissionsFromUser。// Flutter侧发起请求 await _channel.invokeMethod(requestCameraPermission); // ArkTS侧响应 let atManager abilityAccessCtrl.createAtManager(); atManager.requestPermissionsFromUser(context, [ohos.permission.CAMERA]);这里有个体验细节建议在进入扫码页之前先申请权限不要在已经开始预览后才发现没权限否则用户会看到一片黑或闪退。4. 短信二维码生成从协议格式到图片输出的完整实现这个功能是整个项目的核心重点。很多人以为生成二维码就是把字符串丢给二维码库但实际上短信二维码有专门的格式协议不按协议来生成的码扫出来要么不识别要么不会唤起短信编辑页。4.1 短信二维码的格式协议SMSTO与其它变体短信二维码的标准格式是SMSTO协议规定如下SMSTO:手机号码:短信内容例如SMSTO:13800138000:你好这是测试短信整个字符串直接编码成二维码图片扫码后手机系统或扫码App会识别到SMSTO:前缀唤起短信编辑器自动填入收件人和短信正文用户只需要点发送。除了SMSTO还有两种变体我要提醒大家注意sms:号码?body内容部分扫码App支持这种格式但不通用iOS原生相机对它的支持不如SMSTO稳定直接把手机号变成tel:号码格式编码这种扫码出来是拨打电话而不是发短信语义完全不同不要搞混我在开发时还遇到过扫码App对中文内容编码兼容性的问题。使用SMSTO格式正文含中文时有些扫码App会把中文变成乱码。排查下来原因是用错了字符编码。QR码本身默认支持UTF-8但是部分老旧的扫码库对非ASCII字符集的检测不够智能比较稳妥的做法是编码前把短信内容用UTF-8转义然后对字符串整体做URI编码。4.2 使用qr_flutter在Flutter侧直接绘制二维码确认协议格式后生成二维码就简单了。我选的方案是qr_flutter插件纯Dart实现不涉及原生代码在OpenHarmony上跑无压力。# pubspec.yaml dependencies: qr_flutter: ^4.1.0qr_flutter的核心用法很直观但有几个参数直接决定生成效果QrImageView( data: SMSTO:13800138000:你好这是测试短信, version: QrVersions.auto, size: 300.0, gapless: false, // 关闭像素间隔提高扫码识别率 errorCorrectionLevel: QrErrorCorrectLevel.M, eyeStyle: QrEyeStyle( eyeShape: QrEyeShape.square, color: Colors.black, ), dataModuleStyle: QrDataModuleStyle( dataModuleShape: QrDataModuleShape.square, color: Colors.black, ), )参数要点拆解gapless是否让二维码模块黑白方块之间零间隙。默认在屏幕上渲染会有间隙但导出图片时建议设成false让色块连续布满扫码识别率显著提高errorCorrectionLevel纠错等级。短信内容短用M15%容错完全够用二维码也不至于过密。如果你的短信内容很长建议用L7%容错保证码的密度不要太高version用QrVersions.auto让库自动计算版本不要手动指定否则内容超出容量时直接报错4.3 生成可保存的图片文件而不是只能读屏QrImageView只是渲染控件用户长按截屏虽然能保存但会带入背景和高光不符合干净的二维码图片标准。更好的做法是直接用RepaintBoundary把二维码控件绘制成图片文件保存。FutureUint8List _generateQrImageData(String data) async { final boundary _qrKey.currentContext!.findRenderObject() as RenderRepaintBoundary; final image await boundary.toImage(pixelRatio: 3.0); // 3倍像素保证清晰度 final byteData await image.toByteData(format: ui.ImageByteFormat.png); return byteData!.buffer.asUint8List(); }pixelRatio参数很关键默认1.0得到的图片尺寸等于控件尺寸只有300x300打印出来会模糊。设成3.0能拿到900x900的PNG效果完全不一样。拿到PNG字节后保存到相册在OpenHarmony上又是一道桥接。Flutter侧可以先用path_provider拿到应用沙盒路径存文件再调用原生接口把图片保存到系统相册。当时的做法是final dir await getApplicationDocumentsDirectory(); final file File(${dir.path}/sms_qr.png); await file.writeAsBytes(bytes); // 通过MethodChannel告知ArkTS侧执行相册保存 await _channel.invokeMethod(saveImageToGallery, {path: file.path});ArkTS侧相册保存需要用到媒体库接口具体实现要写在原生模块里大致逻辑是把图片写入媒体库或者调用photoAccessHelper的接口导入。由于这一步跟设备版本强相关强烈建议做兼容降级如果系统相册写入失败至少保证图片已经存在沙盒提示用户手动导出。4.4 长短信内容的容量限制与方案取舍二维码不是无限容量的。短信内容一旦超过100个字符二维码密度会急剧上升扫码识别的成功率直线下降。实测数据可以参考这张表短信内容长度二维码版本模块数量识别难度20字符含号码Version 329x29极易60字符含号码Version 537x37容易120字符Version 745x45中等200字符Version 953x53明显变难所以我在产品上做了两个约定短信内容超过160字符时生成前明确提示内容过长二维码可能难以识别提供仅编码手机号的模式扫出来只填入收件人正文由用户自己输入这两个约定在真实使用中非常有必要尤其是一些老年用户会输入很长的文案然后抱怨扫不出来。4.5 中文字符与特殊字符的兼容处理短信内容里的中文、标点符号、公式符号等不能直接拼进SMSTO:字符串。我在项目里做了统一的文本清洗函数String buildSmsQrData(String phone, String message) { final safePhone phone.replaceAll(RegExp(r[^0-9\-]), ); final encodedMessage Uri.encodeComponent(message.trim()); return SMSTO:${safePhone}:$encodedMessage; }这里Uri.encodeComponent会把中文转成UTF-8的百分号编码序列扫码App识别出SMSTO格式后一般能正确解码。我测试了华为、小米、OPPO自带相机扫码以及微信和支付宝的扫一扫除了个别老版本系统的短信编辑器对百分号编码的解码有兼容问题现代版本基本都能正确还原出中文。5. 组件通信与状态管理扫描结果和生成页面的数据流组织二维码工具App页面不多但涉及时实相机帧处理、扫码结果回传、生成表单输入、图片保存状态等多个状态源状态管理做得不好代码很快就乱。5.1 为什么选Provider而不是setState或其它框架考虑到项目体量我选了Provider。理由有几点OpenHarmony分支的Flutter对高版本状态管理库的兼容性还需要验证Provider依赖少、纯Dart实现风险最低扫码页的控制器、生成页的文本控制器、全局的权限状态用ChangeNotifier包装成几个Model数据流清晰团队其他成员对Riverpod不熟Provider的上手成本几乎为零模块划分大致是这样class ScanController extends ChangeNotifier { String? lastScanResult; bool isScanning false; // 扫码中逻辑... } class QrGenerateController extends ChangeNotifier { final TextEditingController phoneController TextEditingController(); final TextEditingController messageController TextEditingController(); Uint8List? qrImageData; String? generateError; // 生成逻辑... } class PermissionController extends ChangeNotifier { bool cameraGranted false; // 权限申请逻辑... }5.2 扫码结果到短信发送页的联动需求里有个交互细节扫码识别出短信二维码后不能只把结果文本展示出来要能一键跳转到发短信页面回填解析出的号码和内容。解析逻辑({String phone, String message})? parseSmsQrData(String raw) { if (raw.startsWith(SMSTO:)) { final body raw.substring(6); final colonIndex body.indexOf(:); if (colonIndex 0) { final phone body.substring(0, colonIndex); final message Uri.decodeComponent(body.substring(colonIndex 1)); return (phone: phone, message: message); } } return null; }在Flutter的页面路由上扫描结果页面识别到SMSTO:前缀后直接把解析结果传进生成页手机号自动填进输入框正文也一并带入。这样用户扫别人给的短信码还能在生成页重新编辑再生成新码形成闭环。Provider在这种跨页面传值场景下很好用不用显式传构造参数只要在根组件注册好ChangeNotifier页面里context.readQrGenerateController()拿到控制器就能改数据。return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) PermissionController()), ChangeNotifierProvider(create: (_) ScanController()), ChangeNotifierProvider(create: (_) QrGenerateController()), ], child: MaterialApp( home: HomePage(), ), );5.3 回调陷阱不要跨异步上下文滥用contextOpenHarmony上Flutter的应用生命周期跟Android有差异页面在后台时如果异步任务还在跑使用context去Navigator.push会偶发异常。我处理的方法是用GlobalKeyNavigatorState做路由跳转而不是在异步回调里拿BuildContext。final navigatorKey GlobalKeyNavigatorState(); // 在扫码线程完成解析后 await _parseAndSaveResult(); if (navigatorKey.currentContext ! null) { navigatorKey.currentState!.push(MaterialPageRoute( builder: (_) SmsEditPage(parsed: result), )); }这个细节极其重要我一开始在相机帧回调里直接用了Navigator.of(context)偶尔闪退。换成全局navigatorKey后稳定了。特别是在OpenHarmony的Flutter适配还不算特别成熟的阶段尽量规避这种跨生命周期操作。6. 真机调试与性能调优从小米平板到OpenHarmony开发板整个项目开发完进入真机调试阶段问题才开始密集暴露。OpenHarmony的生态设备参差不齐从手机、平板到开发板屏幕比例、相机质量、系统API实现差异巨大。6.1 我的真机测试矩阵我分别在以下设备上做了验证设备系统版本相机能力结果润和DAYU200开发板OpenHarmony 4.0后置单摄支持1080p扫码可用帧率偏低某OpenHarmony手机设备API 10主摄正常全功能通过模拟器API 9无相机仅验证生成功能开发板的相机帧率明显低预览画面卡顿主要原因是CPU软解码加上Flutter渲染链路较长。优化手段是前面提到的降分辨率将预览设置从1920x1080降到1280x720帧数从30降到20肉眼几乎无感知但帧处理耗时从500ms降到了200ms以内。6.2 相机预览旋转与二维码方向的关系真机上还有一个经典问题竖屏扫码时相机传感器拿到的帧方向默认是横的二维码在帧里的坐标系跟预览画面有90度旋转偏差。如果你直接把原始帧送进解码器竖立的二维码会解不出来。OpenHarmony的相机接口提供了ImageRotation之类的参数Flutter的camera插件在OpenHarmony适配分支里预览图的旋转处理不如Android成熟。我的做法是在采集到帧后用Dart侧的逻辑做一次旋转修正ui.Image rotateImage(ui.Image src, int angle) { // 90/180/270度旋转的实现 }具体判断是横屏还是竖屏可以在页面初始化时拿到设备方向再配合相机传感器方向做固定旋转。这个值的正确性决定了扫码识别率值得反复校准。6.3 生成图片在部分设备上变绿的问题我测试时发现一个诡异问题RepaintBoundary.toImage生成的PNG在OpenHarmony设备上用系统相册打开时个别图片出现绿色条纹或色彩偏移。排查后确认是Flutter引擎的Impeller/软渲染后端对某些格式的颜色空间标注不同导致的。解决办法第一步用ImageByteFormat.rawRgba获取原始RGBA数据再用原生API重新编码PNG第二步如果不行就强制设置图片的像素格式。同时建议生成前把二维码画到纯白背景上避免透明通道引发颜色空间解析异常。// 先绘制白底再截取 final recorder ui.PictureRecorder(); final canvas Canvas(recorder); canvas.drawRect( Rect.fromLTWH(0, 0, size, size), Paint()..color Colors.white, ); // 将二维码绘制到白底上层这个小改动解决了大部分设备的颜色偏差。6.4 动态权限被拒的兜底逻辑OpenHarmony部分老旧设备上动态权限弹窗可能不出现直接返回拒绝。我做了两种兜底扫码页顶部显示相机未授权点击去授权按钮点击后再次拉起系统权限页如果连续两次被拒引导用户到系统设置中手动开启这个兜底逻辑在开发板上尤其重要因为有些定制系统把权限弹窗阉割了。7. 经验总结这套方案的边界与后续优化方向项目交付后我复盘了整个开发过程。有几条经验值得写下来。第一Flutter for OpenHarmony的成熟度已经可以支撑工具类App但是要预留桥接层的开发量。不要指望Flutter官方插件全都能在鸿蒙上直接跑像相机、相册、传感器这类系统能力大概率需要在ArkTS侧写适配代码。做技术选型时要先把桥接工作量估进排期。第二二维码生成的坑不在画图而在数据格式。很多人用qr_flutter生成一个看起来是短信二维码的码结果扫码后只是显示一行SMSTO字符串没有唤起短信编辑器。原因就是没有严格遵循SMSTO协议或者内容编码不规范。协议细节和编码兼容性是这类功能真正的护城河。第三性能优化要早做。相机的帧分辨率、解码频率、图片保存方式这些参数的取舍最好在架构设计阶段就定下来否则项目后期不断改容易引入难排查的bug。这个项目后续还有几个方向可以继续深挖。比如把SMSTO协议扩展成支持国际区号自动判断号码格式或者加一个最近生成记录功能用本地数据库保存历史短信模板更进阶一点可以接入OpenHarmony的系统分享能力把生成的二维码图片一键分享到短信、邮件或其他应用。如果你也在做OpenHarmony上的Flutter应用尤其是涉及到相机和二维码的场景希望这篇实战记录能帮你少走弯路。尤其是短信二维码生成那一段强烈建议先把协议和编码理清楚再谈界面和用户体验。工具类App的核心价值往往就在这些不起眼的细节里。

相关新闻

论文反复修改到心累?资深教授推荐这几个一键生成论文工具

论文反复修改到心累?资深教授推荐这几个一键生成论文工具

想写论文又快又好,关键是用对 AI 工具、走对流程——资深教授普遍推荐:千笔AI(中文全流程首选) 豆包学术版(轻量高效) DeepSeek 学术版(理工 / 长文本) Grammarly Academic&#xff…

2026/10/7 13:43:43 阅读更多 →
多智能体深度强化学习在车联网资源分配中的应用:MADDPG源码解析与调参实战

多智能体深度强化学习在车联网资源分配中的应用:MADDPG源码解析与调参实战

简介:基于多智能体深度强化学习的车联网频谱共享与资源分配优化源码包,面向车联网通信、深度学习与强化学习领域的研究人员和开发者。项目针对车辆高移动性导致信道快速变化、集中式资源管理受限的问题,将V2V链路复用V2I链路频谱建模为多智能…

2026/10/7 13:42:43 阅读更多 →
从59%到90%:Text-to-ES|QL工程化实战与LOOKUP JOIN避坑指南

从59%到90%:Text-to-ES|QL工程化实战与LOOKUP JOIN避坑指南

1. 为什么“最好的 LLM 也只有 59% 正确率”这件事值得单独聊第一次看到“最好的 LLM 只有 59% 的时间能写出正确的 ES|QL”这个结论时,我的反应不是惊讶,而是“终于有人把这件事量化出来了”。过去一年多,我一直在做 Text-to-SQL 相关的落地…

2026/10/7 13:42:43 阅读更多 →

最新新闻

90DaysOfDevOps 实践笔记:使用 Docker Compose 本地部署 ELK Stack 并完成日志可视化

90DaysOfDevOps 实践笔记:使用 Docker Compose 本地部署 ELK Stack 并完成日志可视化

文档/教程 【免费下载链接】90DaysOfDevOps This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Pri…

2026/10/7 14:13:09 阅读更多 →
【Agent Harness实战】继“紧箍咒”之后,我又给AI Agent装了一套“进化系统”:用TaoToken统一Key打通多工具链路

【Agent Harness实战】继“紧箍咒”之后,我又给AI Agent装了一套“进化系统”:用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/7 14:13:09 阅读更多 →
ADODB 无连接 RecordSet 实战:用 TaoToken 统一 Key 打通离线数据校验

ADODB 无连接 RecordSet 实战:用 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/7 14:13:09 阅读更多 →
利用AI Agent开发AI新闻分析生产级项目(三):把Codex auth.json改到TaoToken

利用AI Agent开发AI新闻分析生产级项目(三):把Codex auth.json改到TaoToken

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

2026/10/7 14:13:09 阅读更多 →
用 PyPDF2 + reportlab 批量给多份装修合同 PDF 加骑缝水印和页码(附完整代码)

用 PyPDF2 + reportlab 批量给多份装修合同 PDF 加骑缝水印和页码(附完整代码)

做装修项目最怕两件事:合同版本混乱、纸质件被调包。把多份合同 PDF 统一加上"骑缝水印 连续页码",既能防篡改,又能让归档一目了然。本文用一个纯 Python 脚本,读完即可跑。 为什么不用在线工具 装修合同含业主姓名、电…

2026/10/7 14:13:09 阅读更多 →
深挖 Harness Engineering:从 Codex 到 Agent 的工程化落地全解析

深挖 Harness Engineering:从 Codex 到 Agent 的工程化落地全解析

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

2026/10/7 14:12:09 阅读更多 →

日新闻

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

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

2026/10/7 1:01:58 阅读更多 →
用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

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

2026/10/7 1:02:00 阅读更多 →
芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

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

2026/10/7 1:02:00 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/6 7:15:40 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/6 5:29:09 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/7 9:29:10 阅读更多 →

月新闻

我发现了一个新思路:用 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/6 8:21:32 阅读更多 →
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/7 11:43:46 阅读更多 →
黑夜航拍船只数据集训练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/7 13:34:55 阅读更多 →