From 45d01a9ad70e65e0d7bbf14f4e3422fc672f5756 Mon Sep 17 00:00:00 2001 From: WilliamVerhaeghe Date: Mon, 30 Dec 2024 17:20:07 +0100 Subject: [PATCH] Version bump + fix issue with imagefit and forceInsideCropArea --- CHANGELOG.md | 4 +++ example/lib/main.dart | 1 + example/pubspec.lock | 2 +- .../calculate_crop_fit_params.dart | 12 ++++++++- .../calculators/calculate_on_crop_params.dart | 26 ++++++++++++++----- lib/src/widgets/custom_image_crop_widget.dart | 10 ++++--- pubspec.yaml | 2 +- 7 files changed, 44 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9bad5d..28b7100 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [0.1.1] - 2024-12-30 + +- Fixed issues with imagefit and forceInsideCropArea resulting in crops outside the crop area and/or wrong crops + ## [0.1.0] - 2024-12-30 - Added maskShape so you can crop using a different mask than for visualisation (e.g. circle mask for visualisation, but square mask for cropping) diff --git a/example/lib/main.dart b/example/lib/main.dart index 02d6d5f..0f51c6d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -102,6 +102,7 @@ class _MyHomePageState extends State { Expanded( child: CustomImageCrop( cropController: controller, + // forceInsideCropArea: true, image: const AssetImage( 'assets/test.png'), // Any Imageprovider will work, try with a AssetImage or NetworkImage for example... // image: const NetworkImage('https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png'), diff --git a/example/pubspec.lock b/example/pubspec.lock index 8d959b5..c393cb0 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -49,7 +49,7 @@ packages: path: ".." relative: true source: path - version: "0.1.0" + version: "0.1.1" fake_async: dependency: transitive description: diff --git a/lib/src/calculators/calculate_crop_fit_params.dart b/lib/src/calculators/calculate_crop_fit_params.dart index 1fc89ef..f67be86 100644 --- a/lib/src/calculators/calculate_crop_fit_params.dart +++ b/lib/src/calculators/calculate_crop_fit_params.dart @@ -12,6 +12,7 @@ CropFitParams calculateCropFitParams({ required int imageHeight, required CustomImageFit imageFit, required double aspectRatio, + required bool forceInsideCropArea, }) { /// the width of the area to crop final double cropSizeWidth; @@ -20,7 +21,7 @@ CropFitParams calculateCropFitParams({ final double cropSizeHeight; /// used to adjust image scale - final double defaultScale; + double defaultScale; switch (imageFit) { case CustomImageFit.fillCropSpace: @@ -118,6 +119,15 @@ CropFitParams calculateCropFitParams({ break; } + if (forceInsideCropArea) { + if (imageWidth * defaultScale < cropSizeWidth) { + defaultScale = cropSizeWidth / imageWidth; + } + if (imageHeight * defaultScale < cropSizeHeight) { + defaultScale = cropSizeHeight / imageHeight; + } + } + return CropFitParams( cropSizeWidth: cropSizeWidth, cropSizeHeight: cropSizeHeight, diff --git a/lib/src/calculators/calculate_on_crop_params.dart b/lib/src/calculators/calculate_on_crop_params.dart index d1cac1e..d03756b 100644 --- a/lib/src/calculators/calculate_on_crop_params.dart +++ b/lib/src/calculators/calculate_on_crop_params.dart @@ -4,7 +4,7 @@ import 'package:custom_image_crop/src/models/params_model.dart'; import 'package:custom_image_crop/src/widgets/custom_image_crop_widget.dart'; /// Returns params to use for cropping image. -OnCropParams caclulateOnCropParams({ +OnCropParams calculateOnCropParams({ required double screenWidth, required double screenHeight, required double cropPercentage, @@ -13,6 +13,7 @@ OnCropParams caclulateOnCropParams({ required int imageWidth, required int imageHeight, required CustomImageFit imageFit, + required bool forceInsideCropArea, }) { /// the size of the area to crop (width and/or height depending on the aspect ratio) final double cropSizeMax; @@ -21,7 +22,7 @@ OnCropParams caclulateOnCropParams({ final double translateScale; /// used to adjust image scale - final double scale; + double scale; /// Temp variable used to calculate the translateScale final double uiSize; @@ -55,16 +56,16 @@ OnCropParams caclulateOnCropParams({ break; case CustomImageFit.fillCropWidth: - uiSize = screenWidth; cropSizeMax = imageWidth / min(1, aspectRatio); - translateScale = cropSizeMax / (uiSize * cropPercentage); + translateScale = + cropSizeMax / (min(screenWidth, screenHeight) * cropPercentage); scale = dataScale; break; case CustomImageFit.fillCropHeight: - uiSize = screenHeight; cropSizeMax = imageHeight * max(1, aspectRatio); - translateScale = cropSizeMax / (uiSize * cropPercentage); + translateScale = + cropSizeMax / (min(screenWidth, screenHeight) * cropPercentage); scale = dataScale; break; @@ -137,6 +138,19 @@ OnCropParams caclulateOnCropParams({ cropSizeHeight = cropSizeMax / aspectRatio; cropSizeWidth = cropSizeHeight * aspectRatio; } + + if (forceInsideCropArea) { + final defaultScale = scale / dataScale; + var newDefaultScale = defaultScale; + if (imageWidth * defaultScale < cropSizeWidth) { + newDefaultScale = cropSizeWidth / imageWidth; + } + if (imageHeight * defaultScale < cropSizeHeight) { + newDefaultScale = cropSizeHeight / imageHeight; + } + scale = scale / defaultScale * newDefaultScale; + } + return OnCropParams( cropSizeHeight: cropSizeHeight, cropSizeWidth: cropSizeWidth, diff --git a/lib/src/widgets/custom_image_crop_widget.dart b/lib/src/widgets/custom_image_crop_widget.dart index 2285b09..fa2b45e 100644 --- a/lib/src/widgets/custom_image_crop_widget.dart +++ b/lib/src/widgets/custom_image_crop_widget.dart @@ -258,6 +258,7 @@ class _CustomImageCropState extends State screenHeight: _height, screenWidth: _width, aspectRatio: (widget.ratio?.width ?? 1) / (widget.ratio?.height ?? 1), + forceInsideCropArea: widget.forceInsideCropArea, ); final scale = data.scale * cropFitParams.additionalScale; _path = _getPath( @@ -384,10 +385,10 @@ class _CustomImageCropState extends State screenHeight: _height, screenWidth: _width, aspectRatio: (widget.ratio?.width ?? 1) / (widget.ratio?.height ?? 1), + forceInsideCropArea: widget.forceInsideCropArea, ); - final initialWidth = _imageAsUIImage!.width * cropFitParams.additionalScale; - final initialHeight = - _imageAsUIImage!.height * cropFitParams.additionalScale; + final initialWidth = image.width * cropFitParams.additionalScale; + final initialHeight = image.height * cropFitParams.additionalScale; return Rect.fromLTWH( (_width - initialWidth) / 2, (_height - initialHeight) / 2, @@ -629,7 +630,7 @@ class _CustomImageCropState extends State final imageHeight = _imageAsUIImage!.height; final pictureRecorder = ui.PictureRecorder(); final canvas = Canvas(pictureRecorder); - final onCropParams = caclulateOnCropParams( + final onCropParams = calculateOnCropParams( cropPercentage: widget.cropPercentage, imageFit: widget.imageFit, imageHeight: imageHeight, @@ -638,6 +639,7 @@ class _CustomImageCropState extends State screenWidth: _width, dataScale: data.scale, aspectRatio: (widget.ratio?.width ?? 1) / (widget.ratio?.height ?? 1), + forceInsideCropArea: widget.forceInsideCropArea, ); final clipPath = Path.from(_getPath( cropWidth: onCropParams.cropSizeWidth, diff --git a/pubspec.yaml b/pubspec.yaml index efbfb99..649078a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: custom_image_crop description: An image cropper that is customizable. You can rotate, scale and translate either through gestures or a controller -version: 0.1.0 +version: 0.1.1 homepage: https://github.com/icapps/flutter-custom-image-crop environment: