diff --git a/QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs b/QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs index 7a145a8..6a31136 100644 --- a/QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs +++ b/QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs @@ -60,7 +60,7 @@ public void can_create_standard_qrcode_graphic_with_background() var result = HelperFunctions.BitmapToHash(bmp); - result.ShouldBe("b9ecef2ee7e769d17f5e00914c7452bb"); + result.ShouldBe("0ee19045007db3c29f2fc75f33906e49"); } [Fact] diff --git a/QRCoder.Core/Renderers/ArtQRCode.cs b/QRCoder.Core/Renderers/ArtQRCode.cs index d68dfeb..549e9ee 100644 --- a/QRCoder.Core/Renderers/ArtQRCode.cs +++ b/QRCoder.Core/Renderers/ArtQRCode.cs @@ -197,11 +197,23 @@ private SKBitmap RenderGraphicCore(int pixelsPerModule, SKColor darkSKColor, SKC if (backgroundImage != null) { if (backgroundImageStyle == BackgroundImageStyle.Fill) - graphics.DrawBitmap(Resize(backgroundImage, size), 0, 0); + { + using (var resizedImage = Resize(backgroundImage, size)) + { + if (resizedImage != null) + graphics.DrawBitmap(resizedImage, 0, 0); + graphics.Flush(); + } + } else if (backgroundImageStyle == BackgroundImageStyle.DataAreaOnly) { var bgOffset = 4 - offset; - graphics.DrawBitmap(Resize(backgroundImage, size - (2 * bgOffset * pixelsPerModule)), 0 + (bgOffset * pixelsPerModule), (bgOffset * pixelsPerModule)); + using (var resizedImage = Resize(backgroundImage, size - (2 * bgOffset * pixelsPerModule))) + { + if (resizedImage != null) + graphics.DrawBitmap(resizedImage, 0 + (bgOffset * pixelsPerModule), (bgOffset * pixelsPerModule)); + graphics.Flush(); + } } } @@ -316,34 +328,34 @@ private static bool IsPartOfFinderPattern(int x, int y, int numModules, int offs /// /// Resize to a square bitmap, but maintain the aspect ratio by padding transparently. /// - /// - /// - /// Resized image as bitmap - private SKBitmap Resize(SKBitmap image, int newSize) + /// Source image to resize. + /// Target side length of the square output. + /// Resized image as bitmap, or null if the source image is invalid. + private static SKBitmap Resize(SKBitmap image, int newSize) { - if (image == null) return null; + if (image == null || image.Width == 0 || image.Height == 0 || newSize <= 0) + return null; float scale = Math.Min((float)newSize / image.Width, (float)newSize / image.Height); - var scaledWidth = (int)(image.Width * scale); - var scaledHeight = (int)(image.Height * scale); + var scaledWidth = Math.Max(1, (int)(image.Width * scale)); + var scaledHeight = Math.Max(1, (int)(image.Height * scale)); var offsetX = (newSize - scaledWidth) / 2; var offsetY = (newSize - scaledHeight) / 2; - var scaledImage = new SKBitmap(scaledWidth, scaledHeight); - - var bm = new SKBitmap(newSize, newSize); - - using (var graphics = new SKCanvas(bm)) + using (var scaledImage = image.Resize(new SKSizeI(scaledWidth, scaledHeight), new SKSamplingOptions(SKFilterMode.Linear))) { - using (var brush = new SKPaint { Color = SKColors.Transparent, }) - { - graphics.DrawRect(new SKRect(0, 0, newSize, newSize), brush); - brush.IsAntialias = true; + if (scaledImage == null) + return null; - graphics.DrawBitmap(scaledImage, new SKRect(offsetX, offsetY, offsetX + scaledWidth, offsetY + scaledHeight)); + var bm = new SKBitmap(newSize, newSize); + using (var graphics = new SKCanvas(bm)) + { + graphics.Clear(SKColors.Transparent); + graphics.DrawBitmap(scaledImage, offsetX, offsetY); + graphics.Flush(); } + return bm; } - return bm; } ///