flutter 给图片添加背景水印

利用canvas给图片背景画上文字水印

import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

//拿到图片的字节数组
Future<ui.Image> loadImageByFile(String path) async {
  var list = await File(path).readAsBytes();
  return loadImageByUint8List(list);
}

//通过[Uint8List]获取图片
Future<ui.Image> loadImageByUint8List(Uint8List list) async {
  ui.Codec codec = await ui.instantiateImageCodec(list);
  ui.FrameInfo frame = await codec.getNextFrame();
  return frame.image;
}

//图片加文字
imageAddWaterMark(String imagePath, String textStr) async {
  int width, height;

  //拿到Canvas
  ui.PictureRecorder recorder = new ui.PictureRecorder();
  Canvas canvas = new Canvas(recorder);

  //拿到Image对象
  ui.Image image = await loadImageByFile(imagePath);
  width = image.width;
  height = image.height;
  // 计算四边形的对角线长度
  double dimension = math.sqrt(math.pow(image.width, 2) + math.pow(image.height, 2));
  canvas.drawImage(image, Offset(0, 0), Paint());
  canvas.saveLayer(Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()), Paint()..blendMode = BlendMode.multiply);
  var text = textStr;
  // 完整覆盖下的正方形面积
  var rectSize = math.pow(dimension, 2);
  // 根据面积与字符大小计算文本重复次数
  int textRepeating = ((rectSize / math.pow(30, 2) * 2) / (text.length + 8)).round(); // text.length + padding 是因为要添加个空格字符

  math.Point pivotPoint = math.Point(dimension / 2, dimension / 2);
  canvas.translate(pivotPoint.x.toDouble(), pivotPoint.y.toDouble());
  canvas.rotate(-25 * math.pi / 180);
  canvas.translate(-pivotPoint.distanceTo(math.Point(0, image.height)), -pivotPoint.distanceTo(math.Point(0, 0))); // 计算文本区域起始坐标分别到图片左侧顶部与底部的距离,作为文本区域移动的距离。
  var textPainter = TextPainter(
    text: TextSpan(text: (text.padRight(text.length + 8)) * textRepeating, style: TextStyle(fontSize: 30, color: Color.fromRGBO(0, 0, 0, .3), height: 2)),
    maxLines: null,
    textDirection: ui.TextDirection.ltr,
    textAlign: TextAlign.start,
  );
  textPainter.layout(maxWidth: dimension);
  textPainter.paint(canvas, Offset.zero);

  canvas.restore();

  ui.Picture picture = recorder.endRecording();
  final img = await picture.toImage(width.toInt(), height.toInt());

  final pngBytes = await img.toByteData(format: ui.ImageByteFormat.png);

  final Directory _directory = await getTemporaryDirectory();
  final Directory _imageDirectory = await new Directory('${_directory.path}/image/').create(recursive: true);
  String _targetPath = _imageDirectory.path;

  File file = File('${_targetPath}watermark${DateTime.now().millisecondsSinceEpoch}.png');
  print(file.path);
  file.writeAsBytesSync(pngBytes!.buffer.asInt8List());

  return file;
}

posted @ 2022-07-26 12:07  小猪ab  阅读(873)  评论(0编辑  收藏  举报