Flutter 鸿蒙应用AR功能集成实战:多平台AR框架+模拟模式,打造增强现实体验

news2026/4/30 0:38:14
Flutter 鸿蒙应用AR功能集成实战多平台AR框架模拟模式打造增强现实体验欢迎加入开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net 文章摘要本文为 Flutter for OpenHarmony 跨平台应用开发任务 41 实战教程完整实现应用AR增强现实功能通过多平台AR框架设计与模拟AR模式在鸿蒙设备上打造基础AR体验。基于前序启动优化、数据验证、权限管理等能力完成了AR服务框架封装、权限管理集成、AR场景组件开发、交互功能实现、展示页面开发全流程落地同时实现了多平台支持、模拟平面检测、3D物体放置、视角旋转等核心能力。所有代码在 macOS DevEco Studio 环境开发兼容开源鸿蒙真机与模拟器通过模拟模式解决了鸿蒙系统暂不支持ARCore/ARKit的问题可直接集成到现有项目为应用增添增强现实体验。 文章目录 前言 功能目标与技术要点 步骤1创建多平台AR服务框架 步骤2实现AR权限管理 步骤3开发AR场景组件与交互功能 步骤4创建AR展示页面 步骤5集成到主应用与国际化适配 运行效果展示⚠️ 鸿蒙平台兼容性注意事项✅ 开源鸿蒙设备验证结果 功能亮点与扩展方向 全文总结 前言增强现实AR是当前移动应用的热门技术趋势能为用户带来沉浸式的交互体验。但在开源鸿蒙平台上由于系统暂不直接支持ARCore或ARKit直接集成主流AR库存在兼容性问题。为了在鸿蒙设备上实现AR功能同时保持多平台兼容性本次开发任务41集成AR功能实现增强现实体验核心目标是设计灵活的多平台AR框架通过模拟AR模式在鸿蒙设备上提供基础AR体验同时为未来支持鸿蒙原生AR预留扩展空间。整体方案基于抽象接口设计支持多种AR后端ARCore、ARKit、Web、模拟通过模拟模式解决鸿蒙设备的兼容性问题同时深度集成前序实现的权限管理能力无需复杂的原生对接可快速集成到现有项目实现“多平台框架模拟模式完整交互”的AR体验闭环。 功能目标与技术要点一、核心目标设计灵活的多平台AR框架支持ARCore、ARKit、Web、模拟等多种后端集成项目现有的权限管理实现相机权限的自动申请与状态处理实现AR场景的显示与交互包括平面检测、3D物体放置、视角旋转等通过模拟AR模式在不支持ARCore/ARKit的鸿蒙设备上提供基础AR体验完成全量中英文国际化适配覆盖所有AR相关文本全量兼容开源鸿蒙设备验证AR功能的实际效果二、核心技术要点多平台框架基于抽象接口设计支持ARCore、ARKit、Web、模拟等多种AR后端模拟模式SimulatedARBackend在不支持原生AR的设备上提供模拟的AR体验核心数据结构ARAnchor锚点、ARPlane平面、ARHitResult点击测试、ARLightEstimate光照估计权限管理集成项目现有的PermissionService自动申请相机权限交互功能点击放置物体、拖动旋转视角、平面检测、物体类型选择UI组件ARSceneWidget、ARObjectPicker、ARPlacementIndicator、ARInfoPanel鸿蒙兼容通过模拟模式解决鸿蒙系统暂不支持ARCore/ARKit的问题国际化支持中英文无缝切换覆盖所有AR相关文本 步骤1创建多平台AR服务框架首先在 lib/services/ 目录下创建 ar_service.dart设计多平台AR框架定义核心数据结构、抽象接口、多种后端实现包括模拟AR后端为整个AR功能奠定基础。1.1 核心数据结构与枚举定义首先定义AR平台类型、核心数据模型ARAnchor、ARPlane、ARHitResult、ARLightEstimate。1.2 AR后端抽象接口定义ARBackend抽象接口包含初始化、平面检测、点击测试、锚点管理、状态监听等核心方法。1.3 模拟AR后端实现实现SimulatedARBackend在不支持原生AR的设备上提供模拟的AR体验包括模拟平面检测、物体放置、视角旋转等。1.4 AR服务封装封装ARService统一管理AR后端、权限、状态提供简洁的调用接口。核心代码结构简化版import ‘dart:async’;import ‘package:flutter/foundation.dart’;import ‘package:flutter/material.dart’;import ‘permission_service.dart’;/// AR平台类型枚举enum ARPlatform {arcore, // Android ARCorearkit, // iOS ARKitopenharmony, // 鸿蒙系统web, // Web平台simulated // 模拟AR}/// AR锚点模型class ARAnchor {final String id;final Offset position;final double rotation;final String? objectType;const ARAnchor({required this.id,required this.position,this.rotation 0.0,this.objectType,});}/// AR平面模型class ARPlane {final String id;final Offset center;final Size size;final bool isHorizontal;const ARPlane({required this.id,required this.center,required this.size,this.isHorizontal true,});}/// AR点击测试结果class ARHitResult {final ARPlane? plane;final Offset position;final double distance;const ARHitResult({this.plane,required this.position,required this.distance,});}/// AR光照估计class ARLightEstimate {final double ambientIntensity;final Color? ambientColor;const ARLightEstimate({this.ambientIntensity 1.0,this.ambientColor,});}/// AR后端抽象接口abstract class ARBackend {Future initialize();void dispose();StreamList get planeStream;Stream get lightEstimateStream;FutureList hitTest(Offset position);Future addAnchor(Offset position, {String? objectType});Future removeAnchor(String anchorId);List get anchors;void updateRotation(double delta);double get currentRotation;}/// 模拟AR后端用于鸿蒙等不支持原生AR的平台class SimulatedARBackend implements ARBackend {final StreamControllerList _planeController StreamController.broadcast();final StreamController _lightController StreamController.broadcast();final List _anchors [];final List _planes [];double _rotation 0.0;bool _isInitialized false;overrideFuture initialize() async {if (_isInitialized) return true;// 模拟初始化await Future.delayed(const Duration(milliseconds: 500));// 生成模拟平面_planes.add(const ARPlane(id: ‘simulated_plane_1’,center: Offset(0.5, 0.6),size: Size(0.8, 0.8),isHorizontal: true,));_planeController.add(List.unmodifiable(_planes));_lightController.add(const ARLightEstimate(ambientIntensity: 1.0));_isInitialized true;return true;}overrideStreamList get planeStream _planeController.stream;overrideStream get lightEstimateStream _lightController.stream;overrideFutureList hitTest(Offset position) async {// 模拟点击测试return [ARHitResult(plane: _planes.firstOrNull,position: position,distance: 1.0,),];}overrideFuture addAnchor(Offset position, {String? objectType}) async {final anchor ARAnchor(id: DateTime.now().millisecondsSinceEpoch.toString(),position: position,rotation: _rotation,objectType: objectType,);_anchors.add(anchor);return anchor;}overrideFuture removeAnchor(String anchorId) async {_anchors.removeWhere((a) a.id anchorId);}overrideList get anchors List.unmodifiable(_anchors);overridevoid updateRotation(double delta) {_rotation delta;}overridedouble get currentRotation _rotation;overridevoid dispose() {_planeController.close();_lightController.close();}}/// AR服务class ARService {ARBackend? _backend;final PermissionService _permissionService PermissionService.instance;bool _isInitialized false;/// 单例实例static final ARService instance ARService._internal();ARService._internal();/// 获取当前AR平台ARPlatform get currentPlatform {// 根据平台返回对应类型鸿蒙返回simulatedreturn ARPlatform.simulated;}/// 是否支持原生ARbool get supportsNativeAR false;/// 初始化AR服务Future initialize() async {if (_isInitialized) return true;// 1. 检查并请求相机权限final hasPermission await _checkAndRequestPermission();if (!hasPermission) {return false;}// 2. 创建AR后端鸿蒙使用模拟后端_backend SimulatedARBackend();// 3. 初始化后端final success await _backend!.initialize();_isInitialized success;return success;}/// 检查并请求相机权限Future _checkAndRequestPermission() async {// 集成项目现有的权限服务// 简化实现实际使用项目的PermissionServicereturn true;}// 其他方法代理到_backendARBackend? get backend _backend;bool get isInitialized _isInitialized;} 步骤2实现AR权限管理AR功能需要相机权限直接集成项目前序实现的 PermissionService实现权限状态检查、自动申请、权限拒绝处理等能力。2.1 权限集成实现在 ARService 中集成 PermissionService在初始化时自动检查并请求相机权限处理权限拒绝的场景引导用户到系统设置。2.2 权限状态UI提示在AR场景组件中根据权限状态显示不同的UI权限已授权显示AR场景权限未申请显示权限申请按钮权限已拒绝显示权限说明与引导按钮权限永久拒绝显示引导到系统设置的按钮 步骤3开发AR场景组件与交互功能在 lib/widgets/ 目录下创建 ar_widgets.dart封装AR场景相关的UI组件实现完整的AR交互功能。3.1 核心AR组件ARSceneWidgetAR场景主组件负责相机预览或模拟场景、平面显示、锚点渲染ARObjectPickerAR物体选择器支持选择立方体、球体、圆柱体等不同类型的3D物体ARPlacementIndicator放置指示器在检测到的平面上显示放置位置提示ARInfoPanelAR信息面板显示平面数量、锚点数量、光照估计等信息ARControlButton控制按钮包括重置、暂停、恢复等3.2 交互功能实现点击放置物体监听屏幕点击事件执行点击测试在点击位置添加AR锚点拖动旋转视角监听水平拖动事件更新AR场景的旋转角度平面检测显示监听平面流在检测到的平面上绘制网格物体类型切换通过物体选择器切换要放置的3D物体类型场景控制重置场景清除所有锚点、暂停/恢复平面检测核心组件结构简化版import ‘package:flutter/material.dart’;import ‘…/services/ar_service.dart’;/// AR场景主组件class ARSceneWidget extends StatefulWidget {const ARSceneWidget({super.key});overrideState createState() _ARSceneWidgetState();}class _ARSceneWidgetState extends State {final ARService _arService ARService.instance;final List _planes [];final List _anchors [];String _selectedObjectType ‘cube’;bool _isPaused false;overridevoid initState() {super.initState();_initializeAR();}Future _initializeAR() async {final success await _arService.initialize();if (success mounted) {_listenToStreams();}}void _listenToStreams() {_arService.backend?.planeStream.listen((planes) {if (mounted) {setState(() _planes.clear()…addAll(planes));}});}void _handleTap(TapUpDetails details) {if (_isPaused) return;final renderBox context.findRenderObject() as RenderBox;final localPosition renderBox.globalToLocal(details.globalPosition);_arService.backend?.hitTest(localPosition).then((results) {if (results.isNotEmpty mounted) {_arService.backend?.addAnchor(results.first.position,objectType: _selectedObjectType,).then((anchor) {if (mounted) {setState(() _anchors.add(anchor));}});}});}void _handlePanUpdate(DragUpdateDetails details) {if (_isPaused) return;_arService.backend?.updateRotation(details.delta.dx * 0.01);if (mounted) setState(() {});}void _resetScene() {for (final anchor in _anchors) {_arService.backend?.removeAnchor(anchor.id);}if (mounted) {setState(() _anchors.clear());}}overrideWidget build(BuildContext context) {if (!_arService.isInitialized) {return const Center(child: CircularProgressIndicator());}return GestureDetector(onTapUp: _handleTap,onPanUpdate: _handlePanUpdate,child: Stack(children: [// 模拟AR背景Container(color: Colors.grey.shade200),// 绘制平面…_planes.map((plane) _buildPlane(plane)),// 绘制锚点…_anchors.map((anchor) _buildAnchor(anchor)),// 放置指示器if (_planes.isNotEmpty) _buildPlacementIndicator(),// 控制按钮_buildControls(),],),);}Widget _buildPlane(ARPlane plane) {return Positioned(left: plane.center.dx * MediaQuery.of(context).size.width - plane.size.width * MediaQuery.of(context).size.width / 2,top: plane.center.dy * MediaQuery.of(context).size.height - plane.size.height * MediaQuery.of(context).size.height / 2,child: Container(width: plane.size.width * MediaQuery.of(context).size.width,height: plane.size.height * MediaQuery.of(context).size.height,decoration: BoxDecoration(border: Border.all(color: Colors.blue.withOpacity(0.5), width: 2),color: Colors.blue.withOpacity(0.1),),child: CustomPaint(painter: _GridPainter()),),);}Widget _buildAnchor(ARAnchor anchor) {final size MediaQuery.of(context).size;return Positioned(left: anchor.position.dx * size.width - 25,top: anchor.position.dy * size.height - 25,child: Transform.rotate(angle: anchor.rotation,child: _build3DObject(anchor.objectType ?? ‘cube’),),);}Widget _build3DObject(String type) {switch (type) {case ‘sphere’:return Container(width: 50,height: 50,decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.green,boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.3),blurRadius: 10,offset: const Offset(0, 5),),],),);case ‘cylinder’:return Container(width: 40,height: 60,decoration: BoxDecoration(color: Colors.orange,borderRadius: BorderRadius.circular(20),boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.3),blurRadius: 10,offset: const Offset(0, 5),),],),);default: // cubereturn Container(width: 50,height: 50,decoration: BoxDecoration(color: Colors.blue,boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.3),blurRadius: 10,offset: const Offset(0, 5),),],),);}}Widget _buildPlacementIndicator() {return Center(child: Container(width: 60,height: 60,decoration: BoxDecoration(shape: BoxShape.circle,border: Border.all(color: Colors.white, width: 3),),child: const Icon(Icons.add, color: Colors.white, size: 30),),);}Widget _buildControls() {return Positioned(bottom: 20,left: 20,right: 20,child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ARControlButton(icon: _isPaused ? Icons.play_arrow : Icons.pause,onPressed: () setState(() _isPaused !_isPaused),),ARObjectPicker(selectedType: _selectedObjectType,onTypeSelected: (type) setState(() _selectedObjectType type),),ARControlButton(icon: Icons.refresh,onPressed: _resetScene,),],),);}}/// 网格绘制器class _GridPainter extends CustomPainter {overridevoid paint(Canvas canvas, Size size) {final paint Paint()…color Colors.blue.withOpacity(0.3)…strokeWidth 1;const step 20.0;for (double x 0; x size.width; x step) {canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint);}for (double y 0; y size.height; y step) {canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);}}overridebool shouldRepaint(covariant CustomPainter oldDelegate) false;}/// 控制按钮class ARControlButton extends StatelessWidget {final IconData icon;final VoidCallback onPressed;const ARControlButton({super.key,required this.icon,required this.onPressed,});overrideWidget build(BuildContext context) {return Container(decoration: BoxDecoration(color: Colors.black.withOpacity(0.5),shape: BoxShape.circle,),child: IconButton(icon: Icon(icon, color: Colors.white),onPressed: onPressed,),);}}/// 物体选择器class ARObjectPicker extends StatelessWidget {final String selectedType;final Function(String) onTypeSelected;const ARObjectPicker({super.key,required this.selectedType,required this.onTypeSelected,});overrideWidget build(BuildContext context) {return PopupMenuButton(initialValue: selectedType,onSelected: onTypeSelected,itemBuilder: (context) [const PopupMenuItem(value: ‘cube’, child: Text(‘立方体’)),const PopupMenuItem(value: ‘sphere’, child: Text(‘球体’)),const PopupMenuItem(value: ‘cylinder’, child: Text(‘圆柱体’)),],child: Container(padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),decoration: BoxDecoration(color: Colors.black.withOpacity(0.5),borderRadius: BorderRadius.circular(20),),child: const Row(mainAxisSize: MainAxisSize.min,children: [Icon(Icons.category, color: Colors.white),SizedBox(width: 8),Text(‘选择物体’, style: TextStyle(color: Colors.white)),],),),);}} 步骤4创建AR展示页面在 lib/screens/ 目录下创建 ar_showcase_page.dart实现AR展示页面包含AR体验入口、功能说明、设置对话框等同时在 lib/utils/localization.dart 中添加国际化支持。4.1 AR展示页面结构AR体验入口功能卡片展示点击进入AR场景功能说明列出AR功能的特点与使用说明设置对话框AR相关设置比如物体类型默认值、是否显示平面网格等权限引导如果没有相机权限显示权限引导4.2 国际化适配在 localization.dart 中添加AR功能相关的中英文翻译文本覆盖所有AR相关的页面文本、提示语、按钮文案。 步骤5集成到主应用与国际化适配5.1 注册页面路由在主应用的路由配置中添加AR展示页面路由MaterialApp(routes: {// 其他已有路由‘/arShowcase’: (context) const ARShowcasePage(),},);5.2 添加设置页面入口在应用的设置页面添加AR体验功能入口ListTile(leading: const Icon(Icons.view_in_ar),title: Text(AppLocalizations.of(context)!.arExperience),onTap: () {Navigator.pushNamed(context, ‘/arShowcase’);},) 运行效果展示模拟AR模式在鸿蒙设备上自动切换到模拟AR模式提供基础AR体验平面检测显示模拟检测到的平面显示蓝色网格直观展示可放置区域3D物体放置点击屏幕放置立方体、球体、圆柱体等3D物体支持切换物体类型视角旋转交互水平拖动屏幕旋转视角3D物体跟随旋转放置指示器在屏幕中心显示放置指示器提示可放置位置场景控制支持暂停/恢复平面检测、重置场景清除所有物体信息面板显示平面数量、锚点数量、光照估计等AR信息鸿蒙设备适配所有页面在鸿蒙设备上无布局溢出交互流畅⚠️ 鸿蒙平台兼容性注意事项ARCore/ARKit不支持鸿蒙系统暂不直接支持ARCore或ARKit本次实现使用模拟AR模式提供基础体验相机权限申请需在 module.json5 中声明相机权限 ohos.permission.CAMERA同时使用项目现有的权限服务申请相机预览模拟模式下使用纯色背景替代真实相机预览未来可集成鸿蒙原生相机API性能优化模拟模式下避免同时放置过多3D物体防止卡顿建议限制锚点数量未来扩展鸿蒙系统未来可能推出原生AR SDK当前框架已预留扩展接口可快速切换到原生AR后端权限引导用户拒绝相机权限后需提供清晰的引导说明权限用途引导用户到系统设置开启✅ 开源鸿蒙设备验证结果本次功能验证分别在OpenHarmony API 10 虚拟机和真机上进行全流程测试所有功能的可用性、稳定性、兼容性测试结果如下AR服务框架初始化正常自动选择模拟AR后端权限管理集成正常相机权限申请、状态检查、拒绝处理均正常模拟AR模式正常工作平面检测、物体放置、视角旋转均正常AR场景组件正常显示无布局溢出、无渲染异常交互功能正常点击放置物体、拖动旋转视角、物体类型切换均正常AR展示页面正常功能卡片、说明、设置对话框均正常国际化适配正常中英文语言切换正常所有文本均正确适配连续多次使用AR功能无内存泄漏、无应用崩溃稳定性表现优异所有功能在不同系统版本、不同尺寸的鸿蒙真机上均正常运行无平台兼容性问题 功能亮点与扩展方向核心功能亮点灵活的多平台AR框架基于抽象接口设计支持ARCore、ARKit、Web、模拟等多种后端模拟AR模式在不支持原生AR的鸿蒙设备上提供基础AR体验解决兼容性问题完整的权限管理深度集成项目现有的权限服务自动申请相机权限处理拒绝场景丰富的交互功能点击放置物体、拖动旋转视角、平面检测、物体类型切换可复用的UI组件封装开箱即用的AR场景组件无需重复开发预留扩展空间框架设计预留了鸿蒙原生AR的扩展接口未来可快速切换纯Dart实现无原生依赖100%兼容鸿蒙设备易于集成全量国际化适配支持中英文无缝切换适配多语言场景功能扩展方向鸿蒙原生AR集成等待鸿蒙系统推出原生AR SDK快速切换到原生AR后端3D模型支持支持加载自定义3D模型GLB、GLTF格式丰富AR内容图像识别与追踪实现图像识别功能识别特定图片后显示AR内容云锚点支持集成云锚点服务实现多设备共享AR场景多人AR体验支持多人同时参与同一AR场景实现互动AR录制与分享支持录制AR体验视频分享给他人光照与阴影实现更真实的光照估计与阴影渲染提升AR真实感性能优化优化模拟模式的性能支持更多锚点与更复杂的3D物体 全文总结本次任务 41 完整实现了 Flutter 鸿蒙应用AR功能集成通过灵活的多平台AR框架设计与模拟AR模式在鸿蒙设备上成功打造了基础AR体验解决了鸿蒙系统暂不支持ARCore/ARKit的问题同时为未来支持鸿蒙原生AR预留了扩展空间。整套方案基于抽象接口设计支持多种AR后端深度集成了前序实现的权限管理能力无原生依赖、兼容性强、易于扩展。从验证结果看模拟AR模式在鸿蒙设备上运行稳定交互流畅提供了完整的基础AR体验。作为一名大一新生这次实战不仅提升了我 Flutter 抽象设计、状态管理、交互开发的能力也让我对AR技术、多平台兼容设计有了更深入的理解。本文记录的开发流程、代码实现和鸿蒙平台兼容性注意事项均经过 OpenHarmony 设备的全流程验证代码可直接复用希望能帮助其他刚接触 Flutter 鸿蒙开发的同学快速实现应用的AR功能打造有趣的增强现实体验。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…