Flutter:邀请海报,Widget转图片,保存相册

记录下,把页面红色区域内的内容,转成图片后保存到相册的功能

依赖

js 复制代码
# 生成二维码
qr_flutter: ^4.1.0
# 保存图片
image_gallery_saver_plus: ^3.0.5

view

js 复制代码
import 'package:demo/common/index.dart';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';

import 'index.dart';

class SharePage extends GetView<ShareController> {
  const SharePage({super.key});

  // 主视图
  Widget _buildView() {
    return RepaintBoundary(
      key: controller.qrKey,
      child: <Widget>[
        TDImage(
          assetUrl: 'assets/img/user.png',
          width: 100.w,
          height: 100.w,
        ),
        TextWidget.body('邀请码:10086', size: 40.sp),
        QrImageView(
          data: '10086',
          version: QrVersions.auto,
          size: 400.w,
          gapless: false,
          embeddedImage: const AssetImage('assets/img/user.png'),
          embeddedImageStyle: QrEmbeddedImageStyle(
            size: Size(100.w, 100.w),
          ),
        ),
      ].toColumn(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
      ).card(color: Colors.white).tight(width: 750.w, height: 750.w),
    );
  }

  @override
  Widget build(BuildContext context) {
    return GetBuilder<ShareController>(
      init: ShareController(),
      id: "share",
      builder: (_) {
        return Scaffold(
          backgroundColor: const Color(0xffF5F6FA),
          appBar: TDNavBar(
            height: 45,
            title: '邀请码',
            titleFontWeight: FontWeight.w600,
            backgroundColor: Colors.white,
            screenAdaptation: true,
            useDefaultBack: true,
            rightBarItems: [
              TDNavBarItem(
                iconWidget: Text('保存'),
                action: controller.saveQrCode,
              ),
            ],
          ),
          body: SafeArea(
            child: _buildView(),
          ),
        );
      },
    );
  }
}

controller

js 复制代码
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:get/get.dart';
import 'package:image_gallery_saver_plus/image_gallery_saver_plus.dart';

class ShareController extends GetxController {
  final GlobalKey qrKey = GlobalKey();
  
  Future<void> saveQrCode() async {
    try {
      // 获取 RenderRepaintBoundary
      final boundary = qrKey.currentContext!
          .findRenderObject() as RenderRepaintBoundary;
      
      // 等待一下确保UI已经完全渲染
      await Future.delayed(const Duration(milliseconds: 20));
      
      // 将 Widget 转换成图片
      final image = await boundary.toImage(pixelRatio: 3.0);
      
      // 将图片转换成字节数据
      final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
      
      if (byteData != null) {
        // 使用 image_gallery_saver_plus 保存到相册
        final result = await ImageGallerySaverPlus.saveImage(
          byteData.buffer.asUint8List(),
          quality: 100,
          name: "qr_code_${DateTime.now().millisecondsSinceEpoch}"
        );
        
        if (result != null && result['isSuccess']) {
          Get.snackbar('提示', '保存成功');
        } else {
          Get.snackbar('提示', '保存失败,请确保已授予存储权限');
        }
      }
    } catch (e) {
      print('保存失败:$e');
      Get.snackbar('提示', '保存失败,请确保已授予存储权限');
    }
  }
}

AndroidManifest.xml 权限配置

js 复制代码
<!-- 允许应用写入外部存储 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 允许应用读取外部存储 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 允许应用读取媒体图像 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<application
	android:requestLegacyExternalStorage="true">
相关推荐
新镜4 小时前
【Flutter】RefreshIndicator 无法下拉刷新问题
flutter
星秋Eliot5 小时前
Flutter的三棵树
前端·flutter
humiaor9 小时前
Flutter之riverpod状态管理Widget UI详解
flutter·consumer·widget·hooks·provider·riverpod·hookwidget
农夫三拳_有点甜9 小时前
Flutter Stack 组件总结
flutter
MaoJiu10 小时前
Flutter混合开发:在iOS工程中嵌入Flutter Module
flutter·ios
新镜11 小时前
【Flutter】flutter_local_notifications并发下载任务通知实践
flutter
农夫三拳_有点甜16 小时前
Flutter SafeArea 组件总结
flutter
农夫三拳_有点甜16 小时前
Flutter ListTile 组件总结
flutter
星秋Eliot2 天前
认识 Flutter
flutter
tangweiguo030519872 天前
Flutter 根据后台配置动态生成页面完全指南
flutter