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">
相关推荐
Zsnoin能11 小时前
flutter国际化、主题配置、视频播放器UI、扫码功能、水波纹问题
flutter
早起的年轻人11 小时前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
HappyAcmen11 小时前
关于Flutter前端面试题及其答案解析
前端·flutter
coooliang21 小时前
Flutter 中的单例模式
javascript·flutter·单例模式
coooliang21 小时前
Flutter项目中设置安卓启动页
android·flutter
JIngles12321 小时前
flutter将utf-8编码的字节序列转换为中英文字符串
java·javascript·flutter
B.-1 天前
在 Flutter 中实现文件读写
开发语言·学习·flutter·android studio·xcode
freflying11191 天前
使用jenkins构建Android+Flutter项目依赖自动升级带来兼容性问题及Jenkins构建速度慢问题解决
android·flutter·jenkins
机器瓦力1 天前
Flutter应用开发:对象存储管理图片
flutter
江上清风山间明月2 天前
Flutter最简单的路由管理方式Navigator
android·flutter·ios·路由·页面管理·navigator