marco.pms.mobileapp/lib/helpers/widgets/time_stamp_image_helper.dart
Vaibhav Surve d208648350 feat: Add timestamp functionality to images in attendance and expense controllers
- Implemented TimestampImageHelper to add timestamps to images.
- Updated AttendanceController to apply timestamps when capturing images.
- Enhanced AddExpenseController to process images with timestamps.
- Modified ReportTaskActionController and ReportTaskController to include timestamping for images.
- Updated UI components to show loading indicators while processing images.
- Refactored image picking logic to handle timestamping and loading states.
2025-10-30 18:03:54 +05:30

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:marco/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
}
}
}