- Updated import paths across multiple files to reflect the new package name. - Changed application name and identifiers in CMakeLists.txt, Runner.rc, and other configuration files. - Modified web index.html and manifest.json to update the app title and name. - Adjusted macOS and Windows project settings to align with the new application name. - Ensured consistency in naming across all relevant files and directories.
98 lines
3.1 KiB
Dart
98 lines
3.1 KiB
Dart
import 'dart:io';
|
|
import 'dart:ui' as ui;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
|
|
|
class TimestampImageHelper {
|
|
/// Adds a timestamp to an image file and returns a new File
|
|
static Future<File> addTimestamp({
|
|
required File imageFile,
|
|
Color textColor = Colors.white,
|
|
double fontSize = 60,
|
|
Color backgroundColor = Colors.black54,
|
|
double padding = 40,
|
|
double bottomPadding = 60,
|
|
}) async {
|
|
try {
|
|
// Read the image file
|
|
final bytes = await imageFile.readAsBytes();
|
|
final originalImage = await decodeImageFromList(bytes);
|
|
|
|
// Create a canvas
|
|
final recorder = ui.PictureRecorder();
|
|
final canvas = Canvas(recorder);
|
|
|
|
// Draw original image
|
|
final paint = Paint();
|
|
canvas.drawImage(originalImage, Offset.zero, paint);
|
|
|
|
// Timestamp text
|
|
final now = DateTime.now();
|
|
final timestamp = DateFormat('dd MMM yyyy hh:mm:ss a').format(now);
|
|
|
|
final textStyle = ui.TextStyle(
|
|
color: textColor,
|
|
fontSize: fontSize,
|
|
fontWeight: FontWeight.bold,
|
|
shadows: [
|
|
const ui.Shadow(
|
|
color: Colors.black,
|
|
offset: Offset(3, 3),
|
|
blurRadius: 6,
|
|
),
|
|
],
|
|
);
|
|
|
|
final paragraphStyle = ui.ParagraphStyle(textAlign: TextAlign.left);
|
|
final paragraphBuilder = ui.ParagraphBuilder(paragraphStyle)
|
|
..pushStyle(textStyle)
|
|
..addText(timestamp);
|
|
|
|
final paragraph = paragraphBuilder.build();
|
|
paragraph.layout(const ui.ParagraphConstraints(width: double.infinity));
|
|
|
|
final textWidth = paragraph.maxIntrinsicWidth;
|
|
final yPosition = originalImage.height - paragraph.height - bottomPadding;
|
|
final xPosition = (originalImage.width - textWidth) / 2;
|
|
|
|
// Draw background
|
|
final backgroundPaint = Paint()
|
|
..color = backgroundColor
|
|
..style = PaintingStyle.fill;
|
|
|
|
final backgroundRect = Rect.fromLTWH(
|
|
xPosition - padding,
|
|
yPosition - 15,
|
|
textWidth + padding * 2,
|
|
paragraph.height + 30,
|
|
);
|
|
|
|
canvas.drawRRect(
|
|
RRect.fromRectAndRadius(backgroundRect, const Radius.circular(8)),
|
|
backgroundPaint,
|
|
);
|
|
|
|
// Draw timestamp text
|
|
canvas.drawParagraph(paragraph, Offset(xPosition, yPosition));
|
|
|
|
// Convert canvas to image
|
|
final picture = recorder.endRecording();
|
|
final img = await picture.toImage(originalImage.width, originalImage.height);
|
|
|
|
final byteData = await img.toByteData(format: ui.ImageByteFormat.png);
|
|
final buffer = byteData!.buffer.asUint8List();
|
|
|
|
// Save to temporary file
|
|
final tempDir = await Directory.systemTemp.createTemp();
|
|
final timestampedFile = File('${tempDir.path}/timestamped_${DateTime.now().millisecondsSinceEpoch}.png');
|
|
await timestampedFile.writeAsBytes(buffer);
|
|
|
|
return timestampedFile;
|
|
} catch (e, stacktrace) {
|
|
logSafe("Error adding timestamp to image", level: LogLevel.error, error: e, stackTrace: stacktrace);
|
|
return imageFile; // fallback
|
|
}
|
|
}
|
|
}
|