Skip to content

Commit 82eca2c

Browse files
WIP working fillcropspace
1 parent 0577e61 commit 82eca2c

File tree

5 files changed

+77
-39
lines changed

5 files changed

+77
-39
lines changed

example/assets/test2.png

81 KB
Loading

example/lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class _MyHomePageState extends State<MyHomePage> {
101101
Expanded(
102102
child: CustomImageCrop(
103103
cropController: controller,
104-
image: const AssetImage('assets/test.png'), // Any Imageprovider will work, try with a NetworkImage for example...
104+
image: const AssetImage('assets/test2.png'), // Any Imageprovider will work, try with a NetworkImage for example...
105105
// image: const NetworkImage('https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png'),
106106
shape: _currentShape,
107107
ratio: _currentShape == CustomCropShape.Ratio ? Ratio(width: _width, height: _height) : null,

example/lib/result_screen.dart

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,36 @@ class ResultScreen extends StatelessWidget {
1616
title: const Text('Result'),
1717
systemOverlayStyle: SystemUiOverlayStyle.dark,
1818
),
19-
body: Center(
20-
child: Column(
21-
children: [
22-
const Spacer(),
23-
Image(
19+
body: Stack(
20+
children: [
21+
Positioned.fill(
22+
child: Container(
23+
decoration: BoxDecoration(
24+
gradient: LinearGradient(
25+
colors: [
26+
Colors.blueGrey.shade400,
27+
Colors.blueGrey.shade600,
28+
],
29+
begin: Alignment.topCenter,
30+
end: Alignment.bottomCenter,
31+
),
32+
)),
33+
),
34+
Center(
35+
child: Image(
2436
image: image,
2537
),
26-
ElevatedButton(
38+
),
39+
Positioned(
40+
bottom: 16,
41+
left: 16,
42+
right: 16,
43+
child: ElevatedButton(
2744
child: const Text('Back'),
2845
onPressed: () => Navigator.of(context).pop(),
2946
),
30-
const Spacer(),
31-
],
32-
),
47+
),
48+
],
3349
),
3450
);
3551
}

lib/src/calculators/calculate_on_crop_params.dart

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ OnCropParams caclulateOnCropParams({
1414
required int imageHeight,
1515
required CustomImageFit imageFit,
1616
}) {
17-
/// the size of the ui screen
18-
final double uiSize;
19-
2017
/// the size of the area to crop (width and/or height depending on the aspect ratio)
2118
final double cropSizeMax;
2219

@@ -28,35 +25,42 @@ OnCropParams caclulateOnCropParams({
2825

2926
switch (imageFit) {
3027
case CustomImageFit.fillCropSpace:
31-
uiSize = min(screenWidth, screenHeight);
32-
cropSizeMax = max(imageWidth, imageHeight).toDouble();
28+
final double uiSize;
29+
if (screenWidth > screenHeight * aspectRatio) {
30+
uiSize = screenHeight;
31+
cropSizeMax = imageHeight.toDouble();
32+
} else {
33+
uiSize = screenWidth;
34+
cropSizeMax = imageWidth.toDouble();
35+
}
3336
translateScale = cropSizeMax / (uiSize * cropPercentage);
3437
scale = dataScale;
3538
break;
3639

3740
case CustomImageFit.fitCropSpace:
38-
uiSize = min(screenWidth, screenHeight);
39-
cropSizeMax = max(imageWidth, imageHeight).toDouble();
41+
final uiSize = min(screenWidth, screenHeight);
42+
cropSizeMax = max(imageWidth / min(1, aspectRatio), imageHeight * max(1, aspectRatio)).toDouble();
4043
translateScale = cropSizeMax / (uiSize * cropPercentage);
4144
scale = dataScale;
4245
break;
4346

4447
case CustomImageFit.fillCropWidth:
45-
uiSize = screenWidth;
46-
cropSizeMax = imageWidth.toDouble();
48+
final uiSize = screenWidth;
49+
cropSizeMax = imageWidth / min(1, aspectRatio);
4750
translateScale = cropSizeMax / (uiSize * cropPercentage);
4851
scale = dataScale;
4952
break;
5053

5154
case CustomImageFit.fillCropHeight:
52-
uiSize = screenHeight;
53-
cropSizeMax = imageHeight.toDouble();
55+
final uiSize = screenHeight;
56+
cropSizeMax = imageHeight * max(1, aspectRatio);
5457
translateScale = cropSizeMax / (uiSize * cropPercentage);
5558
scale = dataScale;
5659
break;
5760

5861
case CustomImageFit.fitVisibleSpace:
59-
if (screenHeight < screenWidth) {
62+
final double uiSize;
63+
if (screenHeight * aspectRatio < screenWidth) {
6064
uiSize = screenHeight;
6165
cropSizeMax = imageHeight.toDouble();
6266
} else {
@@ -70,13 +74,13 @@ OnCropParams caclulateOnCropParams({
7074
case CustomImageFit.fillVisibleSpace:
7175
final heightToWidthRatio = (screenHeight / screenWidth);
7276

73-
if (screenHeight > screenWidth) {
74-
uiSize = screenHeight;
77+
if (screenHeight * aspectRatio > screenWidth) {
78+
final uiSize = screenHeight;
7579
cropSizeMax = imageHeight.toDouble();
7680
translateScale = cropSizeMax / uiSize / cropPercentage * heightToWidthRatio;
7781
scale = dataScale / cropPercentage * heightToWidthRatio;
7882
} else {
79-
uiSize = screenWidth;
83+
final uiSize = screenWidth;
8084
cropSizeMax = imageWidth.toDouble();
8185
translateScale = cropSizeMax / uiSize / cropPercentage / heightToWidthRatio;
8286
scale = dataScale / cropPercentage / heightToWidthRatio;
@@ -85,9 +89,9 @@ OnCropParams caclulateOnCropParams({
8589

8690
case CustomImageFit.fillVisibleHeight:
8791
final heightToWidthRatio = (screenHeight / screenWidth);
88-
uiSize = screenHeight;
92+
final uiSize = screenHeight;
8993
cropSizeMax = imageHeight.toDouble();
90-
if (screenWidth > screenHeight) {
94+
if (screenWidth > screenHeight * aspectRatio) {
9195
translateScale = cropSizeMax / uiSize / cropPercentage;
9296
scale = dataScale / cropPercentage;
9397
} else {
@@ -98,9 +102,9 @@ OnCropParams caclulateOnCropParams({
98102

99103
case CustomImageFit.fillVisiblelWidth:
100104
final heightToWidthRatio = (screenHeight / screenWidth);
101-
uiSize = screenWidth;
105+
final uiSize = screenWidth;
102106
cropSizeMax = imageWidth.toDouble();
103-
if (screenWidth > screenHeight) {
107+
if (screenWidth > screenHeight * aspectRatio) {
104108
translateScale = cropSizeMax / uiSize / cropPercentage / heightToWidthRatio;
105109
scale = dataScale / cropPercentage / heightToWidthRatio;
106110
} else {
@@ -113,11 +117,11 @@ OnCropParams caclulateOnCropParams({
113117
final double cropSizeWidth;
114118
final double cropSizeHeight;
115119
if (aspectRatio > 1) {
116-
cropSizeHeight = cropSizeMax;
117-
cropSizeWidth = cropSizeMax * aspectRatio;
118-
} else {
119120
cropSizeWidth = cropSizeMax;
120-
cropSizeHeight = cropSizeMax / aspectRatio;
121+
cropSizeHeight = cropSizeWidth / aspectRatio;
122+
} else {
123+
cropSizeHeight = cropSizeMax;
124+
cropSizeWidth = cropSizeHeight * aspectRatio;
121125
}
122126
return OnCropParams(
123127
cropSizeHeight: cropSizeHeight,

lib/src/widgets/custom_image_crop_widget.dart

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,9 @@ class _CustomImageCropState extends State<CustomImageCrop> with CustomImageCropL
299299
required double width,
300300
required double height,
301301
required double borderRadius,
302-
bool clipShape = false,
302+
bool clipShape = true,
303303
}) {
304-
if (clipShape) {
304+
if (!clipShape) {
305305
return Path()
306306
..addRect(
307307
Rect.fromCenter(
@@ -376,17 +376,32 @@ class _CustomImageCropState extends State<CustomImageCrop> with CustomImageCropL
376376
clipShape: widget.clipShapeOnCrop,
377377
));
378378
final matrix4Image = Matrix4.diagonal3(vector_math.Vector3.all(1))
379-
..translate(onCropParams.translateScale * data.x + onCropParams.cropSizeWidth / 2, onCropParams.translateScale * data.y + onCropParams.cropSizeHeight / 2)
379+
..translate(
380+
onCropParams.translateScale * data.x + onCropParams.cropSizeWidth / 2,
381+
onCropParams.translateScale * data.y + onCropParams.cropSizeHeight / 2,
382+
)
380383
..scale(onCropParams.scale)
381384
..rotateZ(data.angle);
382385
final bgPaint = Paint()
383386
..color = widget.backgroundColor
384387
..style = PaintingStyle.fill;
385-
canvas.drawRect(Rect.fromLTWH(0, 0, onCropParams.cropSizeWidth, onCropParams.cropSizeHeight), bgPaint);
388+
canvas.drawRect(
389+
Rect.fromLTWH(
390+
0,
391+
0,
392+
onCropParams.cropSizeWidth,
393+
onCropParams.cropSizeHeight,
394+
),
395+
bgPaint,
396+
);
386397
canvas.save();
387398
canvas.clipPath(clipPath);
388399
canvas.transform(matrix4Image.storage);
389-
canvas.drawImage(_imageAsUIImage!, Offset(-imageWidth / 2, -imageHeight / 2), widget.imagePaintDuringCrop);
400+
canvas.drawImage(
401+
_imageAsUIImage!,
402+
Offset(-imageWidth / 2, -imageHeight / 2),
403+
widget.imagePaintDuringCrop,
404+
);
390405
canvas.restore();
391406

392407
// Optionally remove magenta from image by evaluating every pixel
@@ -395,7 +410,10 @@ class _CustomImageCropState extends State<CustomImageCrop> with CustomImageCropL
395410
// final bytes = await compute(computeToByteData, <String, dynamic>{'pictureRecorder': pictureRecorder, 'cropWidth': cropWidth});
396411

397412
ui.Picture picture = pictureRecorder.endRecording();
398-
ui.Image image = await picture.toImage(onCropParams.cropSizeWidth.floor(), onCropParams.cropSizeHeight.floor());
413+
ui.Image image = await picture.toImage(
414+
onCropParams.cropSizeWidth.floor(),
415+
onCropParams.cropSizeHeight.floor(),
416+
);
399417

400418
// Adding compute would be preferrable. Unfortunately we cannot pass an ui image to this.
401419
// A workaround would be to save the image and load it inside of the isolate

0 commit comments

Comments
 (0)