Skip to content

Commit d35a4fc

Browse files
committed
Fix ImageCropper crash for small image
1 parent bb758ac commit d35a4fc

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

CollapseLauncher/Classes/GameManagement/ImageBackground/ImageBackgroundManager.ImageCropperAndConvert.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ public partial class ImageBackgroundManager
9898
ImageCropper cropper = UIElementExtensions
9999
.Create<ImageCropper>(SetImageCropperProperties);
100100

101+
// Skip spawning crop overlay when source dimensions do not meet minimum crop size.
102+
if (!await CanOpenCropOverlay(backgroundImageUri, backgroundCodecType == ImageExternalCodecType.Svg, cropper, token))
103+
{
104+
return (overlayUrlOrPath, backgroundUrlOrPath, false);
105+
}
106+
101107
// -- Register to close dialog if cancellation is triggered outside the event.
102108
token.Register(dialog.Hide);
103109
if (token.IsCancellationRequested)
@@ -186,6 +192,22 @@ void SetImageCropperProperties(ImageCropper element)
186192
}
187193
}
188194

195+
private static async Task<bool> CanOpenCropOverlay(Uri imagePath, bool isSvg, ImageCropper cropper, CancellationToken token)
196+
{
197+
if (isSvg)
198+
{
199+
// SVG has no fixed source pixel size before rasterization, so keep existing behavior.
200+
return true;
201+
}
202+
203+
WriteableBitmap sourceBitmap = new(1, 1);
204+
await using Stream sourceStream = await OpenStreamFromFileOrUrl(imagePath, token);
205+
using IRandomAccessStream randomStream = sourceStream.AsRandomAccessStream(true);
206+
await sourceBitmap.SetSourceAsync(randomStream);
207+
208+
return cropper.CanCropSource(sourceBitmap.PixelWidth, sourceBitmap.PixelHeight);
209+
}
210+
189211
/// <summary>
190212
/// Load the image to <see cref="ImageCropper"/> instance in asynchronous detached manner.
191213
/// </summary>

Hi3Helper.CommunityToolkit/ImageCropper/ImageCropper.Properties.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,24 @@ public partial class ImageCropper
2828
/// </summary>
2929
public Rect CroppedRegion => _currentCroppedRect;
3030

31+
/// <summary>
32+
/// Checks whether the provided source pixel size can be cropped.
33+
/// </summary>
34+
/// <param name="pixelWidth">Source width in pixels.</param>
35+
/// <param name="pixelHeight">Source height in pixels.</param>
36+
/// <returns>True when the source meets the minimum crop size.</returns>
37+
public bool CanCropSource(double pixelWidth, double pixelHeight)
38+
{
39+
var minCropSize = MinCropSize;
40+
return pixelWidth >= minCropSize.Width && pixelHeight >= minCropSize.Height;
41+
}
42+
3143
private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
3244
{
3345
var target = (ImageCropper)d;
3446
if (e.NewValue is BitmapSource bitmap)
3547
{
36-
if (bitmap.PixelWidth < target.MinCropSize.Width || bitmap.PixelHeight < target.MinCropSize.Height)
48+
if (!target.CanCropSource(bitmap.PixelWidth, bitmap.PixelHeight))
3749
{
3850
target.Source = null;
3951
throw new ArgumentException("The resolution of the image is too small!");

0 commit comments

Comments
 (0)