flutter截屏的方式生成图片水印

本文介绍了如何在Flutter应用中使用ImageWaterMarkUtil类实现图片水印功能,并提供了一个示例,展示了如何通过截屏并添加水印后保存到本地。开发者可以使用这个功能来保护图片版权或标识来源。
摘要由CSDN通过智能技术生成
import 'dart:io';
import 'dart:ui' as ui;

import 'package:jade/utils/ImageWaterMarkUtil.dart';
import 'package:util/screen_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
/*
* 截屏的方式生成图片水印
* */
///图片生产水印
class ImageWaterMarkPage extends StatefulWidget {
  //任务ID
  //final Asset imagePath;
  final String imagePath;

  ImageWaterMarkPage(this.imagePath, {Key key}) : super(key: key);

  
  State<ImageWaterMarkPage> createState() => _WaterMarkPageState();
}

class _WaterMarkPageState extends State<ImageWaterMarkPage> {

  GlobalKey _globalKey = GlobalKey();

  get image_watermark => null;



  Future<void> saveSignImg() async {
    //通过globalkey将Widget保存为ui.Image
    ui.Image _image = await ImageWaterMarkUtil.imageLoader.getImageFromWidget(_globalKey);

    ///异步将这张图片保存在手机内部存储目录下
    String localImagePath =  await ImageWaterMarkUtil.imageLoader.saveImageByUIImage(_image, isEncode: false);
    ///保存完毕后关闭当前页面并将保存的图片路径返回到上一个页面
    Get.back(result: localImagePath);
  }
  
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text('水印功能'),),
      body: Column(
        children: [
          InkWell(
            child: Text('保存'),
            onTap: (){
              saveSignImg();
            },
          ),
          Container(
              alignment: Alignment.center,
              child: RepaintBoundary(
                key: _globalKey,
                child: Stack(
                  children: [
                    Image.file(
                      File(widget.imagePath),
                      width: setWidth(600),
                      fit: BoxFit.fitWidth,
                    ),
                    Positioned(
                        top: 2,
                        right: 2,
                        child: Text(
                          "这里是水印内容",
                          style: TextStyle(fontSize: 30.sp, color: Colors.white),
                        ))
                  ],
                ),
              )
          )
        ],
      ),
    );
  }
}
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'dart:ui';
import 'package:crypto/crypto.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart';
import 'package:path_provider/path_provider.dart';

/// 图片加载工具类
class ImageWaterMarkUtil {

  //私有化构造
  ImageWaterMarkUtil._();

  //单例模式创建
  static final ImageWaterMarkUtil imageLoader = ImageWaterMarkUtil._();

  // 将一个Widget转为image.Image对象
  Future<ui.Image> getImageFromWidget(GlobalKey globalKey) async {
    // globalKey为需要图像化的widget的key
    RenderRepaintBoundary boundary =
    globalKey.currentContext?.findRenderObject() as RenderRepaintBoundary;
    // 转换为图像
    ui.Image img = await boundary.toImage();
    return img;
  }

  ///将指定的文件保存到目录空间中。
  ///[image] 这里是使用的ui包下的Image
  ///[picName] 保存到本地的文件(图片)文件名,如test_image
  ///[endFormat]保存到本地的文件(图片)文件格式,如png,
  ///[isReplace]当本地存在同名的文件(图片)时,true就是替换
  ///[isEncode]对保存的文件(图片)进行编码
  ///  最终保存到本地的文件 (图片)的名称为 picName.endFormat
  Future<String> saveImageByUIImage(ui.Image image,
      {String picName,
        String endFormat = "png",
        bool isReplace = true,
        bool isEncode = true}) async {
    ///获取本地磁盘路径
    /*
     * 在Android平台中获取的是/data/user/0/com.studyyoun.flutterbookcode/app_flutter
     * 此方法在在iOS平台获取的是Documents路径
     */
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;

    ///拼接目录
    if (picName == null || picName.trim().length == 0) {
      ///当用户没有指定picName时,取当前的时间命名
      picName = "${DateTime.now().millisecond.toString()}.$endFormat";
    } else {
      picName = "$picName.$endFormat";
    }

    if (isEncode) {
      ///对保存的图片名字加密
      picName = md5.convert(utf8.encode(picName)).toString();
    }

    appDocPath = "$appDocPath/$picName";

    ///校验图片是否存在
    var file = File(appDocPath);
    bool exist = await file.exists();
    if (exist) {
      if (isReplace) {
        ///如果图片存在就进行删除替换
        ///如果新的图片加载失败,那么旧的图片也被删除了
        await file.delete();
      } else {
        ///如果图片存在就不进行下载
        return "";
      }
    }
    ByteData byteData = await image.toByteData(format: ImageByteFormat.png);
    Uint8List pngBytes = byteData.buffer.asUint8List();
    print("保存的图片路径 $appDocPath");

    ///将Uint8List的数据格式保存
    await File(appDocPath).writeAsBytes(pngBytes);

    return appDocPath;
  }
}

调用

//拍照图传至WaterMarkPage返回水印图
Get.to(WaterMarkPage(file!.path))?.then((newSignImg){ });
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter中给图片水印的步骤如下: 1. 将图片载到内存中,可以使用`ImageProvider`或`File`类来载。 2. 创建一个新的画布,并将原始图片绘制到画布上。 3. 在画布上绘制水印,可以使用`TextPainter`类来绘制文字水印,或使用`ImageProvider`类来图片水印。 4. 将绘制完水印的画布保存为新的图片文件。 下面是一个简单的示例代码: ```dart import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'package:image/image.dart' as img; class WatermarkImage extends StatefulWidget { final String imagePath; final String watermarkText; WatermarkImage({required this.imagePath, required this.watermarkText}); @override _WatermarkImageState createState() => _WatermarkImageState(); } class _WatermarkImageState extends State<WatermarkImage> { late String _watermarkImagePath; @override void initState() { super.initState(); _addWatermarkToImage(); } Future<void> _addWatermarkToImage() async { final directory = await getTemporaryDirectory(); final imageFile = File(widget.imagePath); final image = img.decodeImage(imageFile.readAsBytesSync())!; final watermark = img.Image.fromBytes( 100, 50, img.encodePng(img.copyResize( img.decodeImage( (await rootBundle.load('assets/images/watermark.png')).buffer.asUint8List(), )!, width: 100, height: 50, )), ); final textPainter = TextPainter( text: TextSpan( text: widget.watermarkText, style: TextStyle( fontSize: 20, color: Colors.white, ), ), textDirection: TextDirection.ltr, )..layout(); final canvas = img.Canvas(image); canvas.drawImage(watermark, 0, 0); canvas.drawImage( img.copyResize( img.Image.fromBytes( textPainter.width.toInt(), textPainter.height.toInt(), img.encodePng( (await textPainter.toPicture().toImage(textPainter.width.toInt(), textPainter.height.toInt())) .toByteData(format: img.PixelFormat.rgba8888)! .buffer .asUint8List(), ), ), width: 100, height: 50, ), image.width - 100, image.height - 50, ); final watermarkImageFile = File('${directory.path}/watermark_${DateTime.now().millisecondsSinceEpoch}.jpg'); watermarkImageFile.writeAsBytesSync(img.encodeJpg(image)); setState(() { _watermarkImagePath = watermarkImageFile.path; }); } @override Widget build(BuildContext context) { return _watermarkImagePath != null ? Image.file( File(_watermarkImagePath), fit: BoxFit.cover, ) : Container(); } } ``` 这个示例代码将载指定路径的图片文件,并在右下角添一个水印图标和文字水印。最终生成的带有水印的新图片文件将保存在应用程序的临时目录中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值