Flutter Web中syncfusion签名板toImage()方法无法使用问题
问题:Flutter Web中Syncfusion签名板
toImage()方法无法正常工作 我使用syncfusion_flutter_signaturepad: ^21.1.35包实现用户签名功能,移动端运行正常,但Flutter Web上无法工作。看起来toImage()方法在Web环境下不支持,或者我的操作有误?
保存图片代码:
final GlobalKey<SfSignaturePadState> signaturePadKey = GlobalKey<SfSignaturePadState>(); ui.Image data = await signaturePadKey.currentState!.toImage(pixelRatio: 3.0); ByteData? bytes = await data.toByteData(format: ui.ImageByteFormat.png); String imageEncoded = base64.encode(bytes!.buffer.asUint8List());
错误信息:
Error: Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/html/scene_builder.dart:94:16 dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw_ dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3 assertFailed lib/_engine/engine/html/scene_builder.dart 95:34 pushTransform packages/flutter/src/rendering/layer.dart 1414:12 toImage dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/flutter/src/rendering/layer.dart 1404:27 toImage packages/syncfusion_flutter_signaturepad/signaturepad.dart 974:13 toImage dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/syncfusion_flutter_signaturepad/signaturepad.dart 972:27 toImage packages/syncfusion_flutter_signaturepad/signaturepad.dart 372:31 toImage packages/tolk2go_tasker/SignaturePage/signature_view_model.dart 33:33 validatingSignature dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/tolk2go_tasker/SignaturePage/signature_view_model.dart 28:35 validatingSignature packages/tolk2go_tasker/SignaturePage/signature.dart 156:54 <fn> packages/flutter/src/material/ink_well.dart 1072:21 handleTap packages/flutter/src/gestures/recognizer.dart 253:24 invokeCallback packages/flutter/src/gestures/tap.dart 627:11 handleTapUp packages/flutter/src/gestures/tap.dart 306:5 [_checkUp] packages/flutter/src/gestures/tap.dart 239:7 handlePrimaryPointer packages/flutter/src/gestures/recognizer.dart 615:9 handleEvent packages/flutter/src/gestures/pointer_router.dart 98:12 [_dispatch] packages/flutter/src/gestures/pointer_router.dart 143:9 <fn> dart-sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart 21:13 forEach packages/flutter/src/gestures/pointer_router.dart 141:17 [_dispatchEventToRoutes] packages/flutter/src/gestures/pointer_router.dart 127:7 route packages/flutter/src/gestures/binding.dart 460:19 handleEvent packages/flutter/src/gestures/binding.dart 440:14 dispatchEvent packages/flutter/src/rendering/binding.dart 337:11 dispatchEvent packages/flutter/src/gestures/binding.dart 395:7 [_handlePointerEventImmediately] packages/flutter/src/gestures/binding.dart 357:5 handlePointerEvent packages/flutter/src/gestures/binding.dart 314:7 [_flushPointerEventQueue] packages/flutter/src/gestures/binding.dart 295:7 [_handlePointerDataPacket] lib/_engine/engine/platform_dispatcher.dart 1183:13 invoke1 lib/_engine/engine/platform_dispatcher.dart 244:5 invokeOnPointerDataPacket lib/_engine/engine/pointer_binding.dart 147:39 [_onPointerData] lib/_engine/engine/pointer_binding.dart 653:20 <fn> lib/_engine/engine/pointer_binding.dart 594:14 <fn> lib/_engine/engine/pointer_binding.dart 288:16 loggedHandler lib/_engine/engine/pointer_binding.dart 179:80 <fn> dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 334:14 _checkAndCall dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 339:39 dcall
错误截图:

Flutter Doctor检查结果:
[✓] Flutter (Channel stable, 3.7.8, on macOS 12.6.3 21G419 darwin-x64, locale en-IN) • Flutter version 3.7.8 on channel stable at /Volumes/Backup/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 90c64ed42b (2 days ago), 2023-03-21 11:27:08 -0500 • Engine revision 9aa7816315 • Dart version 2.19.5 • DevTools version 2.20.1 [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1) • Android SDK at /Users/casperonflutter/Library/Android/sdk • Platform android-33, build-tools 33.0.1 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.2) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14C18 • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2022.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301) [✓] VS Code (version 1.76.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.60.0 [✓] Connected device (3 available) • iPhone (2) (mobile) • 00008030-001548E10C32802E • ios • iOS 15.3.1 19D52 • macOS (desktop) • macos • darwin-x64 • macOS 12.6.3 21G419 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 111.0.5563.110 [✓] HTTP Host Availability • All required HTTP hosts are available • No issues found!
解决方案
这个问题源于Flutter Web环境下toImage()方法的渲染层实现限制,Syncfusion签名板针对Web端提供了专门的兼容方案,可通过以下方式解决:
方法1:使用Syncfusion官方Web导出API
直接替换原有toImage()流程,使用toPngBytes()方法获取PNG字节数据:
import 'dart:typed_data'; import 'package:syncfusion_flutter_signaturepad/syncfusion_flutter_signaturepad.dart'; // 替换原保存逻辑 final Uint8List? bytes = await signaturePadKey.currentState!.toPngBytes(pixelRatio: 3.0); if (bytes != null) { String imageEncoded = base64.encode(bytes); // 后续处理编码后的字符串 }
这是Syncfusion官方针对Web环境提供的兼容方案,无需额外依赖。
方法2:Canvas手动捕获(备选)
如果上述方法无效,可直接操作Web的Canvas元素捕获签名:
import 'dart:typed_data'; import 'dart:io' if (dart.library.html) 'dart:html' as html; // 获取签名板对应的Canvas final RenderObject? renderObject = signaturePadKey.currentContext?.findRenderObject(); final html.CanvasElement? canvas = renderObject?.toImageSync() as html.CanvasElement?; if (canvas != null) { // 将Canvas转为PNG字节 final String dataUrl = canvas.toDataUrl('image/png'); final Uint8List bytes = base64.decode(dataUrl.split(',').last); String imageEncoded = base64.encode(bytes); // 后续处理 }
注意:需用条件编译区分Web和移动端,避免非Web环境报错。
额外建议
- 升级Syncfusion签名板包到最新稳定版本,官方可能已修复Web端兼容性问题;
- 使用CanvasKit渲染器启动Web项目(默认HTML渲染器部分API支持有限):
flutter run -d chrome --web-renderer canvaskit
内容的提问来源于stack exchange,提问作者Senthur Kumaran
相关产品推荐
相关产品推荐

