/
controller.dart
125 lines (104 loc) · 4.2 KB
/
controller.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:native_image_cropper/native_image_cropper.dart';
import 'package:native_image_cropper_platform_interface/native_image_cropper_platform_interface.dart';
/// The [CropController] manages the state and behaviour of image cropping.
/// It holds data such as image size, crop mode, image rectangle, and crop
/// rectangle, as well as a reference to the image data.
final class CropController {
/// Stores the size of the image to be cropped.
final imageSizeNotifier = ValueNotifier<Size?>(null);
/// Stores the image's position and size within the view.
final imageRectNotifier = ValueNotifier<Rect?>(null);
/// Stores the selected crop area within the view.
final cropRectNotifier = ValueNotifier<Rect?>(null);
/// Stores the [CropMode] of the image to be cropped.
final modeNotifier = ValueNotifier<CropMode>(CropMode.rect);
/// Stores the image data to be cropped.
Uint8List? bytes;
/// Gets the image [Size] stored in the [ValueNotifier].
Size? get imageSize => imageSizeNotifier.value;
/// Sets the new image [Size] in the [ValueNotifier].
set imageSize(Size? value) => imageSizeNotifier.value = value;
/// Gets the image [Rect] stored in the [ValueNotifier].
Rect? get imageRect => imageRectNotifier.value;
/// Sets the new image [Rect] in the [ValueNotifier].
set imageRect(Rect? value) => imageRectNotifier.value = value;
/// Gets the crop [Rect] stored in the [ValueNotifier].
Rect? get cropRect => cropRectNotifier.value;
/// Sets the new crop [Rect] in the [ValueNotifier].
set cropRect(Rect? value) => cropRectNotifier.value = value;
/// Gets the [CropMode] stored in the [ValueNotifier].
CropMode get mode => modeNotifier.value;
/// Sets the new [CropMode]]in the [ValueNotifier].
set mode(CropMode value) => modeNotifier.value = value;
/// Calculates the crop size based on the relative positions of the
/// [cropRect], [imageRect] and the original [imageSize].
Size get cropSize {
if ((cropRect, imageRect, imageSize)
case (
final Rect cropRect,
final Rect imageRect,
final Size imageSize,
)) {
final width = cropRect.width / imageRect.width * imageSize.width;
final height = cropRect.height / imageRect.height * imageSize.height;
return Size(width, height);
}
throw const NativeImageCropperException(
'NullPointerException',
'Crop rect, image rect or image size are not initialized!',
);
}
/// Performs the actual cropping by calling the corresponding
/// [NativeImageCropper] method.
/// You can additionally set the [ImageFormat] for compression, defaults to
/// [ImageFormat.jpg].
Future<Uint8List> crop({ImageFormat format = ImageFormat.jpg}) {
if ((cropRect, imageRect, imageSize, bytes)
case (
final Rect cropRect,
final Rect imageRect,
final Size imageSize,
final Uint8List bytes,
)) {
final x = (cropRect.left / imageRect.width * imageSize.width).toInt();
final y = (cropRect.top / imageRect.height * imageSize.height).toInt();
final width = cropSize.width.toInt();
final height = cropSize.height.toInt();
return switch (modeNotifier.value) {
CropMode.oval => NativeImageCropper.cropOval(
bytes: bytes,
x: x,
y: y,
width: width,
height: height,
format: format,
),
CropMode.rect => NativeImageCropper.cropRect(
bytes: bytes,
x: x,
y: y,
width: width,
height: height,
format: format,
),
};
}
throw const NativeImageCropperException(
'NullPointerException',
'Bytes, crop rect, image rect or image size are not initialized!',
);
}
/// Releases the resources held by the [ValueNotifier].
void dispose() {
imageSizeNotifier.dispose();
imageRectNotifier.dispose();
cropRectNotifier.dispose();
modeNotifier.dispose();
}
@override
String toString() =>
'CropController{bytes: ${bytes?.lengthInBytes}, imageSize: $imageSize, '
'imageRect: $imageRect, cropRect: $cropRect, mode: $mode}';
}