Flutter中使用Image.drawString实现自定义字体大小的方案咨询
解决方案:自定义字号添加图片文字水印
针对你使用image库drawString时无法自定义字号的问题,提供两种可行方案,适配你的Flutter 3.19.0和image ^4.1.7版本:
方案一:使用自定义TTF字体生成指定字号
image库支持加载外部TTF字体并生成任意字号的字体对象,步骤如下:
- 添加字体资源:将所需字体文件(如
arial.ttf)放入项目assets/fonts目录,并在pubspec.yaml中声明:
flutter: assets: - assets/fonts/arial.ttf
- 加载字体并绘制水印:
import 'package:flutter/services.dart'; import 'package:image/image.dart' as img; Future<img.Image> addCustomSizeWatermark( img.Image originalImage, String watermarkText, double targetFontSize, int xPos, int yPos, ) async { // 从assets加载TTF字体文件 final fontBytes = await rootBundle.load('assets/fonts/arial.ttf'); final ttfFont = img.TtfFont.fromBytes(fontBytes.buffer.asUint8List()); // 生成指定字号的字体对象 final customFont = img.Font.fromTtf(ttfFont, targetFontSize); // 绘制自定义字号的文字水印 img.drawString( originalImage, watermarkText, x: xPos, y: yPos, color: img.ColorFloat32.rgb(255, 255, 255), font: customFont, ); return originalImage; }
方案二:借助Flutter Canvas实现灵活文字渲染
如果需要更丰富的文字样式(如粗体、阴影)或更精准的渲染效果,可以用Flutter的Canvas绘制图片和文字,再导出为图片:
import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:image/image.dart' as img; Future<img.Image> addWatermarkWithCanvas( img.Image originalImage, String watermarkText, double fontSize, ) async { // 将image库的图片转换为Flutter ui.Image final uiImage = await ui.decodeImageFromList(img.encodePng(originalImage)); // 创建绘制记录器 final recorder = ui.PictureRecorder(); final canvas = Canvas(recorder); // 绘制原图 canvas.drawImage(uiImage, Offset.zero, Paint()); // 配置文字样式(支持任意字号、颜色、字体) final textStyle = TextStyle( color: Colors.white, fontSize: fontSize, fontFamily: 'Arial', fontWeight: FontWeight.w500, // 可选:添加粗体 ); final textPainter = TextPainter( text: TextSpan(text: watermarkText, style: textStyle), textDirection: TextDirection.ltr, ); // 计算文字布局 textPainter.layout(); // 示例:将文字放在右下角(可根据需求调整坐标) final x = originalImage.width - textPainter.width - 15; final y = originalImage.height - textPainter.height - 15; // 绘制文字 textPainter.paint(canvas, Offset(x, y)); // 导出为图片 final picture = recorder.endRecording(); final finalUiImage = await picture.toImage(originalImage.width, originalImage.height); final byteData = await finalUiImage.toByteData(format: ui.ImageByteFormat.png); return img.decodePng(byteData!.buffer.asUint8List())!; }
方案对比
- 方案一:纯依赖
image库,无需Flutter UI环境,适合后台处理场景,但字体渲染样式有限。 - 方案二:利用Flutter Canvas,支持所有TextStyle配置,渲染效果更细腻,但需要在Flutter UI环境中执行。
内容的提问来源于stack exchange,提问作者Mayur Sankhla
相关产品推荐
相关产品推荐

