Files
rtime/lib/images_manager.dart

130 lines
3.8 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import 'package:uuid/uuid.dart';
import 'package:image/image.dart' as img;
import 'package:image_cropper/image_cropper.dart' as img_cropper;
class ImagesManager {
static final ImagesManager instance = ImagesManager._internal();
ImagesManager._internal();
static final Logger log = Logger("ImagesManager");
static Uri? _imagesDirectory;
Future<Uri> get imageDirectory async {
if (_imagesDirectory != null) return _imagesDirectory!;
await _initImagesDirectory();
return _imagesDirectory!;
}
Future _initImagesDirectory() async {
final directoryLoc = await getApplicationDocumentsDirectory();
final directoryName = "images";
final directoryPath = path.join(directoryLoc.path, directoryName);
final directoryUri = Uri.directory(directoryPath);
final directory = Directory.fromUri(directoryUri);
if (!await directory.exists()) {
log.info("Image directory does not yet exist. Creating it.");
}
await directory.create(recursive: true);
log.info("Image directory set up at '$directory'");
_imagesDirectory = directoryUri;
}
Future<String?> createImage(ImageSource source) async {
final XFile? ximage = await ImagePicker().pickImage(source: source);
if (ximage == null) return null;
final uuid = Uuid().v6();
final imageDir = await imageDirectory;
final finalPath = path.join(
imageDir.path,
uuid + path.extension(ximage.name),
);
final tempPath = path.join(
imageDir.path,
"${uuid}_tocrop${path.extension(ximage.name)}",
);
await ximage.saveTo(tempPath);
img_cropper.CroppedFile? cropped = await img_cropper.ImageCropper().cropImage(
sourcePath: tempPath,
aspectRatio: const img_cropper.CropAspectRatio(ratioX: 1.0, ratioY: 1.0),
uiSettings: [
img_cropper.AndroidUiSettings(
toolbarTitle: "Crop image",
toolbarColor: Colors.black,
toolbarWidgetColor: Colors.white,
),
img_cropper.IOSUiSettings(title: "Crop image"),
],
);
if (cropped == null) {
await File(tempPath).delete();
return null;
}
await File(finalPath).writeAsBytes(await cropped.readAsBytes());
await File(tempPath).delete();
return uuid;
}
Future<Image?> loadImage(String imageUuid) async {
final imageDir = await imageDirectory;
if (!Uuid.isValidUUID(fromString: imageUuid)) {
log.warning(
"Tried to load an image with an invalid UUID : '$imageUuid'.",
);
return null;
}
final imagePath = path.join(imageDir.path, "$imageUuid.jpg");
final file = File(imagePath);
if (!await file.exists()) {
log.warning("Tried to load an image that does not exist: '$imagePath'.");
return null;
}
return Image.file(file);
}
Future<bool> deleteImage(String imageUuid) async {
final imageDir = await imageDirectory;
if (!Uuid.isValidUUID(fromString: imageUuid)) {
log.warning(
"Tried to delete an image with an invalid UUID : '$imageUuid'.",
);
return false;
}
final imagePath = path.join(imageDir.path, "$imageUuid.jpg");
final file = File(imagePath);
if (await file.exists()) {
try {
await file.delete();
log.info("Image with UUID '$imageUuid' deleted successfully.");
return true;
} catch (e) {
log.severe("Error deleting image with UUID '$imageUuid': $e");
return false;
}
} else {
log.warning("Tried to delete an image that does not exist: '$imagePath'.");
return false;
}
}
}