水印相机前端

This commit is contained in:
2026-09-28 09:59:43 +08:00
parent 187a7e0911
commit c5b3d81d07
19 changed files with 2761 additions and 3 deletions
+79
View File
@@ -0,0 +1,79 @@
import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_test/flutter_test.dart';
import 'package:image/image.dart' as img;
import 'package:qiangbao_accounting/models/watermark.dart';
import 'package:qiangbao_accounting/pages/watermark/watermark_painter.dart';
/// 把水印渲染到一张模拟背景上并**写出图片文件**,用来用眼睛验收排版。
///
/// 为什么需要它:单元测试只能断言「不报错、尺寸对」,断言不了「好不好看」。
/// 之前正是靠看图才发现「时间:2026.09.28 14:30」是 19 个字、被折行阈值切成
/// 两行、最后一个「0」孤零零占了一行。
///
/// 跑法:
/// ```
/// flutter test test/watermark_preview_test.dart
/// ```
/// 输出图片的路径会打印在结果里,直接用图片查看器打开即可。
///
/// 注意:测试环境没有中文字体,汉字会渲染成方块(Ahem 测试字体)——
/// **这是正常的**,看的是排版/位置/颜色,不是字形。真机上才是真汉字。
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
/// 造一张「有明有暗」的底图,用来检查白字在浅色区域会不会糊
img.Image makeBackground(int w, int h) {
final bg = img.Image(width: w, height: h);
for (var y = 0; y < h; y++) {
for (var x = 0; x < w; x++) {
final t = x / w;
var v = (215 - 150 * t).round(); // 左亮右暗
if (y > h * 0.55 && y < h * 0.62) v = 235; // 一条浅色横带,模拟高光
bg.setPixelRgb(x, y, v, (v * 0.96).round(), (v * 0.9).round());
}
}
return bg;
}
test('渲染一张水印预览图供人工核对', () async {
final iconData = await rootBundle.load('assets/images/watermark_camera.png');
final codec = await ui.instantiateImageCodec(iconData.buffer.asUint8List());
final brandIcon = (await codec.getNextFrame()).image;
// 全项打开,把四种行和品牌角标都覆盖到
final settings = WatermarkSettings.defaults.copyWith(
showWeather: true,
showRemark: true,
);
final data = WatermarkData(
time: DateTime(2026, 9, 28, 14, 30),
address: '云南省昆明市五华区莲花池正街某小区 3 栋',
weather: '晴',
temperature: '25℃',
remark: '和宝一起吃的那家店',
);
final jpg = await composeWatermarkedJpeg(
originalBytes: img.encodePng(makeBackground(1080, 1440)),
settings: settings,
data: data,
brandIcon: brandIcon,
maxWidth: 1080,
);
// 顺带当一次端到端冒烟:产物必须是能解回来的合法 JPEG
final decoded = img.decodeJpg(jpg);
expect(decoded, isNotNull);
expect(decoded!.width, 1080);
expect(decoded.height, 1440);
final out = File('${Directory.systemTemp.path}/wm_preview.jpg')
..writeAsBytesSync(jpg);
// ignore: avoid_print
print('水印预览图已写出(人工核对用): ${out.path}');
});
}