import 'dart:async'; import 'dart:io'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/scheduler.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:permission_handler/permission_handler.dart'; class ImageSaveService { /// 保存图片到相册 - 改进版本,避免 debugNeedsPaint 错误 static Future saveImageToGallery( GlobalKey repaintBoundaryKey, { String? fileName, }) async { try { // 1. 检查权限 final hasPermission = await _requestPermission(); if (!hasPermission) { debugPrint('没有相册访问权限'); return false; } // 2. 使用调度器确保在正确的时机捕获 final completer = Completer(); SchedulerBinding.instance.addPostFrameCallback((_) async { try { // 额外等待确保所有绘制完成 await Future.delayed(const Duration(milliseconds: 100)); final result = await _captureAndSave(repaintBoundaryKey, fileName); completer.complete(result); } catch (e) { debugPrint('捕获图片失败: $e'); completer.complete(false); } }); return await completer.future; } catch (e) { debugPrint('保存图片失败: $e'); return false; } } /// 内部方法:捕获并保存图片 static Future _captureAndSave( GlobalKey repaintBoundaryKey, String? fileName, ) async { try { // 获取 RepaintBoundary final boundary = repaintBoundaryKey.currentContext?.findRenderObject() as RenderRepaintBoundary?; if (boundary == null) { debugPrint('无法获取RepaintBoundary'); return false; } // 多次尝试捕获,避免绘制冲突 ui.Image? image; int attempts = 0; const maxAttempts = 5; while (attempts < maxAttempts) { try { // 检查是否正在绘制 if (boundary.debugNeedsPaint) { debugPrint( 'RepaintBoundary 正在绘制中,等待... (尝试 ${attempts + 1}/$maxAttempts)', ); await Future.delayed(Duration(milliseconds: 200 * (attempts + 1))); attempts++; continue; } // 尝试捕获图片 image = await boundary.toImage(pixelRatio: 3.0); break; } catch (e) { debugPrint('捕获尝试 ${attempts + 1} 失败: $e'); attempts++; if (attempts < maxAttempts) { await Future.delayed(Duration(milliseconds: 300 * attempts)); } } } if (image == null) { debugPrint('所有捕获尝试都失败了'); return false; } // 转换为字节数据 final byteData = await image.toByteData(format: ui.ImageByteFormat.png); if (byteData == null) { debugPrint('无法转换图片数据'); return false; } final pngBytes = byteData.buffer.asUint8List(); // 保存到相册 final result = await ImageGallerySaver.saveImage( pngBytes, name: fileName ?? 'MoodCanvas_${DateTime.now().millisecondsSinceEpoch}', quality: 100, ); debugPrint('保存结果: $result'); return result['isSuccess'] == true; } catch (e) { debugPrint('_captureAndSave 失败: $e'); return false; } } /// 请求相册访问权限 static Future _requestPermission() async { if (Platform.isIOS) { // iOS 14+ 需要 photos 权限 final status = await Permission.photos.request(); return status.isGranted; } else if (Platform.isAndroid) { // Android 需要存储权限 final status = await Permission.storage.request(); return status.isGranted; } return false; } /// 检查权限状态 static Future checkPermission() async { if (Platform.isIOS) { final status = await Permission.photos.status; return status.isGranted; } else if (Platform.isAndroid) { final status = await Permission.storage.status; return status.isGranted; } return false; } /// 打开应用设置页面 static Future openSettings() async { await openAppSettings(); } }