diff --git a/QRCoder.Core.Tests/Generators/BestPracticesTests.cs b/QRCoder.Core.Tests/Generators/BestPracticesTests.cs index d3701ac..25afd6e 100644 --- a/QRCoder.Core.Tests/Generators/BestPracticesTests.cs +++ b/QRCoder.Core.Tests/Generators/BestPracticesTests.cs @@ -593,7 +593,15 @@ public void Base64QRCode_GetGraphic_WithIcon_ShouldReturnBase64() var b64 = new Base64QRCode(data); var icon = new SKBitmap(10, 10); - var result = b64.GetGraphic(5, SKColors.Black, SKColors.White, icon, 15, 2); + var result = b64.GetGraphic(new Base64QRCodeGraphicOptions + { + PixelsPerModule = 5, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + Icon = icon, + IconSizePercent = 15, + IconBorderWidth = 2 + }); result.ShouldNotBeNullOrEmpty(); } @@ -746,7 +754,14 @@ public void ArtQRCode_GetGraphic_WithCustomPixelSizeFactor_ShouldWork() var data = gen.CreateQrCode("Art pixel", QRCodeGenerator.ECCLevel.H); var art = new ArtQRCode(data); - var bmp = art.GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, pixelSizeFactor: 0.5); + var bmp = art.GetGraphic(new ArtQRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + BackgroundSKColor = SKColors.Transparent, + PixelSizeFactor = 0.5 + }); bmp.ShouldNotBeNull(); } @@ -758,8 +773,14 @@ public void ArtQRCode_GetGraphic_FlatQuietZone_ShouldWork() var data = gen.CreateQrCode("Art flat QZ", QRCodeGenerator.ECCLevel.H); var art = new ArtQRCode(data); - var bmp = art.GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, - quietZoneRenderingStyle: ArtQRCode.QuietZoneStyle.Flat); + var bmp = art.GetGraphic(new ArtQRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + BackgroundSKColor = SKColors.Transparent, + QuietZoneRenderingStyle = ArtQRCode.QuietZoneStyle.Flat + }); bmp.ShouldNotBeNull(); } @@ -772,7 +793,14 @@ public void ArtQRCode_PixelSizeFactor_GreaterThanOne_ShouldThrow() var art = new ArtQRCode(data); Should.Throw(() => - art.GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, pixelSizeFactor: 1.5)); + art.GetGraphic(new ArtQRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + BackgroundSKColor = SKColors.Transparent, + PixelSizeFactor = 1.5 + })); } #endregion diff --git a/QRCoder.Core.Tests/Generators/PayloadGeneratorTests.cs b/QRCoder.Core.Tests/Generators/PayloadGeneratorTests.cs index 312b5c7..9c1c246 100644 --- a/QRCoder.Core.Tests/Generators/PayloadGeneratorTests.cs +++ b/QRCoder.Core.Tests/Generators/PayloadGeneratorTests.cs @@ -1208,9 +1208,9 @@ public void bezahlcode_generator_can_generate_payload_singlepayment_minimal() var bnc = "100205000"; var name = "Wikimedia Fördergesellschaft"; var amount = 10.00m; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount); -#pragma warning restore CS0612 +#pragma warning restore CS0618 generator .ToString() .ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&amount=10,00¤cy=EUR&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + ""); @@ -1227,9 +1227,9 @@ public void bezahlcode_generator_can_generate_payload_singlepayment_full() var amount = 10.00m; var postingKey = 69; Currency currency = Currency.USD; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account, bnc, amount, "", 0, null, null, reason, postingKey, currency, DateTime.Now); -#pragma warning restore CS0612 +#pragma warning restore CS0618 generator .ToString() .ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&postingkey=69&amount=10,00&reason=Thanks%20for%20all%20your%20efforts¤cy=USD&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + ""); @@ -1246,9 +1246,9 @@ public void bezahlcode_generator_can_generate_payload_singledirectdebit() var amount = 10.00m; var postingKey = 69; Currency currency = Currency.USD; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var generator = new PayloadGenerator.BezahlCode(AuthorityType.singledirectdebit, name, account, bnc, amount, "", 0, null, null, reason, postingKey, currency, DateTime.Now); -#pragma warning restore CS0612 +#pragma warning restore CS0618 generator .ToString() .ShouldBe("bank://singledirectdebit?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&postingkey=69&amount=10,00&reason=Thanks%20for%20all%20your%20efforts¤cy=USD&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + ""); @@ -1269,9 +1269,9 @@ public void bezahlcode_generator_can_generate_payload_periodicsinglepayment() var periodicFirstExecutionDate = DateTime.Now; var periodicLastExecutionDate = DateTime.Now.AddMonths(3); Currency currency = Currency.USD; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var generator = new PayloadGenerator.BezahlCode(AuthorityType.periodicsinglepayment, name, account, bnc, amount, periodicTimeunit, periodicTimeunitRotation, periodicFirstExecutionDate, periodicLastExecutionDate, reason, postingKey, currency, DateTime.Now); -#pragma warning restore CS0612 +#pragma warning restore CS0618 generator .ToString() .ShouldBe("bank://periodicsinglepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&postingkey=69&amount=10,00&reason=Thanks%20for%20all%20your%20efforts¤cy=USD&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + "&periodictimeunit=W&periodictimeunitrotation=2&periodicfirstexecutiondate=" + periodicFirstExecutionDate.ToString("ddMMyyyy") + "&periodiclastexecutiondate=" + periodicLastExecutionDate.ToString("ddMMyyyy")); @@ -1439,9 +1439,9 @@ public void bezahlcode_generator_should_handle_account_whitespaces() var bnc = "100205000"; var name = "Wikimedia Fördergesellschaft"; var amount = 10.00m; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount); -#pragma warning restore CS0612 +#pragma warning restore CS0618 generator .ToString() .ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=01194700&bnc=100205000&amount=10,00¤cy=EUR&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + ""); @@ -1455,9 +1455,9 @@ public void bezahlcode_generator_should_handle_bnc_whitespaces() var bnc = "10020 5000"; var name = "Wikimedia Fördergesellschaft"; var amount = 10.00m; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount); -#pragma warning restore CS0612 +#pragma warning restore CS0618 generator .ToString() .ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&amount=10,00¤cy=EUR&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + ""); @@ -1503,9 +1503,9 @@ public void bezahlcode_generator_should_add_decimals() var bnc = "10020 5000"; var name = "Wikimedia Fördergesellschaft"; var amount = 10; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var generator = new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount); -#pragma warning restore CS0612 +#pragma warning restore CS0618 generator .ToString() .ShouldBe("bank://singlepayment?name=Wikimedia%20F%C3%B6rdergesellschaft&account=001194700&bnc=100205000&amount=10,00¤cy=EUR&executiondate=" + DateTime.Now.ToString("ddMMyyyy") + ""); @@ -1518,9 +1518,9 @@ public void bezahlcode_generator_should_throw_wrong_contact_constructor_exceptio var account = "0001194700"; var bnc = "10020 5000"; var name = "Wikimedia Fördergesellschaft"; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account, bnc, "", "", "New business contact.")); -#pragma warning restore CS0612 +#pragma warning restore CS0618 Assert.NotNull(exception); Assert.IsType(exception); exception.Message.ShouldBe("The constructor without an amount may only ne used with authority types 'contact' and 'contact_v2'."); @@ -1572,9 +1572,9 @@ public void bezahlcode_generator_should_throw_wrong_nonsepa_constructor_periodic var periodicFirstExecutionDate = DateTime.Now; var periodicLastExecutionDate = DateTime.Now.AddMonths(3); Currency currency = Currency.USD; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.periodicsinglepayment, name, account, bnc, amount, periodicTimeunit, periodicTimeunitRotation, periodicFirstExecutionDate, periodicLastExecutionDate, reason, postingKey, currency, DateTime.Now)); -#pragma warning restore CS0612 +#pragma warning restore CS0618 Assert.NotNull(exception); Assert.IsType(exception); exception.Message.ShouldBe("When using 'periodicsinglepayment' as authority type, the parameters 'periodicTimeunit' and 'periodicTimeunitRotation' must be set."); @@ -1588,9 +1588,9 @@ public void bezahlcode_generator_should_throw_wrong_sepa_constructor_exception() var bic = "BFSWDE33BER"; var name = "Wikimedia Fördergesellschaft"; var amount = 10.00m; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, iban: iban, bic: bic, amount: amount)); -#pragma warning restore CS0612 +#pragma warning restore CS0618 Assert.NotNull(exception); Assert.IsType(exception); exception.Message.ShouldBe("The constructor with 'iban' and 'bic' may only be used with 'SEPA' authority types. Either choose another authority type or switch constructor."); @@ -1660,9 +1660,9 @@ public void bezahlcode_generator_should_throw_invalid_account_exception() var bnc = "100205000"; var name = "Wikimedia Fördergesellschaft"; var amount = 10.00m; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount)); -#pragma warning restore CS0612 +#pragma warning restore CS0618 Assert.NotNull(exception); Assert.IsType(exception); exception.Message.ShouldBe("The account entered isn't valid."); @@ -1676,9 +1676,9 @@ public void bezahlcode_generator_should_throw_invalid_bnc_exception() var bnc = "10020500023545626226262"; var name = "Wikimedia Fördergesellschaft"; var amount = 10.00m; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount)); -#pragma warning restore CS0612 +#pragma warning restore CS0618 Assert.NotNull(exception); Assert.IsType(exception); exception.Message.ShouldBe("The bnc entered isn't valid."); @@ -1693,9 +1693,9 @@ public void bezahlcode_generator_should_throw_invalid_postingkey_exception() var name = "Wikimedia Fördergesellschaft"; var postingKey = 101; var amount = 10.00m; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account: account, bnc: bnc, amount: amount, postingKey: postingKey)); -#pragma warning restore CS0612 +#pragma warning restore CS0618 Assert.NotNull(exception); Assert.IsType(exception); exception.Message.ShouldBe("PostingKey must be within 0 and 99."); @@ -1840,9 +1840,9 @@ public void bezahlcode_generator_should_throw_invalid_executiondate_exception() var postingKey = 69; var executionDate = new DateTime(2017, 1, 1); Currency currency = Currency.USD; -#pragma warning disable CS0612 +#pragma warning disable CS0618 var exception = Record.Exception(() => new PayloadGenerator.BezahlCode(AuthorityType.singlepayment, name, account, bnc, amount, "", 0, null, null, reason, postingKey, currency, executionDate)); -#pragma warning restore CS0612 +#pragma warning restore CS0618 Assert.NotNull(exception); Assert.IsType(exception); exception.Message.ShouldBe("Execution date must be today or in future."); diff --git a/QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs b/QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs index 6a31136..d4b4bb1 100644 --- a/QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs +++ b/QRCoder.Core.Tests/Renderers/ArtQRCodeRendererTests.cs @@ -31,7 +31,14 @@ public void can_create_standard_qrcode_graphic_with_custom_finder() var gen = new QRCodeGenerator(); var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); var finder = new SKBitmap(15, 15); - var bmp = new ArtQRCode(data).GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, finderPatternImage: finder); + var bmp = new ArtQRCode(data).GetGraphic(new ArtQRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + BackgroundSKColor = SKColors.Transparent, + FinderPatternImage = finder + }); var result = HelperFunctions.BitmapToHash(bmp); result.ShouldBe("442648a1087f78955773c261b45665c9"); @@ -43,7 +50,14 @@ public void can_create_standard_qrcode_graphic_without_quietzone() { var gen = new QRCodeGenerator(); var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); - var bmp = new ArtQRCode(data).GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, drawQuietZones: false); + var bmp = new ArtQRCode(data).GetGraphic(new ArtQRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + BackgroundSKColor = SKColors.Transparent, + DrawQuietZones = false + }); var result = HelperFunctions.BitmapToHash(bmp); result.ShouldBe("4bbf0a58f3dc2c82cae0ad874da92028"); @@ -71,7 +85,14 @@ public void should_throw_pixelfactor_oor_exception() var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); var aCode = new ArtQRCode(data); - var exception = Record.Exception(() => aCode.GetGraphic(10, SKColors.Black, SKColors.White, SKColors.Transparent, pixelSizeFactor: 2)); + var exception = Record.Exception(() => aCode.GetGraphic(new ArtQRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + BackgroundSKColor = SKColors.Transparent, + PixelSizeFactor = 2 + })); Assert.NotNull(exception); Assert.IsType(exception); exception.Message.ShouldContain("pixelSizeFactor"); diff --git a/QRCoder.Core.Tests/Renderers/QRCodeRendererTests.cs b/QRCoder.Core.Tests/Renderers/QRCodeRendererTests.cs index e6bbdfe..d23b422 100644 --- a/QRCoder.Core.Tests/Renderers/QRCodeRendererTests.cs +++ b/QRCoder.Core.Tests/Renderers/QRCodeRendererTests.cs @@ -62,7 +62,13 @@ public void can_create_qrcode_with_transparent_logo_graphic() var gen = new QRCodeGenerator(); var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); - var bmp = new QRCode(data).GetGraphic(10, SKColors.Black, SKColors.Transparent, icon: SKBitmap.Decode(System.IO.Path.Combine(HelperFunctions.GetAssemblyPath(), "assets", "noun_software-engineer_2909346.png"))); + var bmp = new QRCode(data).GetGraphic(new QRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.Transparent, + Icon = SKBitmap.Decode(System.IO.Path.Combine(HelperFunctions.GetAssemblyPath(), "assets", "noun_software-engineer_2909346.png")) + }); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); result.ShouldBe("947e264401b6e4958d8c955c1e8574cb"); @@ -81,7 +87,13 @@ public void can_create_qrcode_with_non_transparent_logo_graphic() //Create QR code var gen = new QRCodeGenerator(); var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); - var bmp = new QRCode(data).GetGraphic(10, SKColors.Black, SKColors.White, icon: SKBitmap.Decode(System.IO.Path.Combine(HelperFunctions.GetAssemblyPath(), "assets", "noun_software-engineer_2909346.png"))); + var bmp = new QRCode(data).GetGraphic(new QRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + Icon = SKBitmap.Decode(System.IO.Path.Combine(HelperFunctions.GetAssemblyPath(), "assets", "noun_software-engineer_2909346.png")) + }); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); @@ -103,7 +115,14 @@ public void can_create_qrcode_with_logo_and_with_transparent_border() var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); var logo = SKBitmap.Decode(System.IO.Path.Combine(HelperFunctions.GetAssemblyPath(), "assets", "noun_software-engineer_2909346.png")); - var bmp = new QRCode(data).GetGraphic(10, SKColors.Black, SKColors.Transparent, icon: logo, iconBorderWidth: 6); + var bmp = new QRCode(data).GetGraphic(new QRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.Transparent, + Icon = logo, + IconBorderWidth = 6 + }); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); result.ShouldBe("947e264401b6e4958d8c955c1e8574cb"); @@ -124,7 +143,14 @@ public void can_create_qrcode_with_logo_and_with_standard_border() var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); var logo = SKBitmap.Decode(System.IO.Path.Combine(HelperFunctions.GetAssemblyPath(), "assets", "noun_software-engineer_2909346.png")); - var bmp = new QRCode(data).GetGraphic(10, SKColors.Black, SKColors.White, icon: logo, iconBorderWidth: 6); + var bmp = new QRCode(data).GetGraphic(new QRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.White, + Icon = logo, + IconBorderWidth = 6 + }); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); result.ShouldBe("09866787899d8f4ab4bd08df75e47e55"); @@ -145,7 +171,15 @@ public void can_create_qrcode_with_logo_and_with_custom_border() var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H); var logo = SKBitmap.Decode(System.IO.Path.Combine(HelperFunctions.GetAssemblyPath(), "assets", "noun_software-engineer_2909346.png")); - var bmp = new QRCode(data).GetGraphic(10, SKColors.Black, SKColors.Transparent, icon: logo, iconBorderWidth: 6, iconBackgroundSKColor: SKColors.DarkGreen); + var bmp = new QRCode(data).GetGraphic(new QRCodeGraphicOptions + { + PixelsPerModule = 10, + DarkSKColor = SKColors.Black, + LightSKColor = SKColors.Transparent, + Icon = logo, + IconBorderWidth = 6, + IconBackgroundSKColor = SKColors.DarkGreen + }); //Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346 var result = HelperFunctions.BitmapToHash(bmp); result.ShouldBe("5e39d9e2a412dfcca26352234b0ce6da"); diff --git a/QRCoder.Core/Renderers/ArtQRCode.cs b/QRCoder.Core/Renderers/ArtQRCode.cs index 549e9ee..1096c0c 100644 --- a/QRCoder.Core/Renderers/ArtQRCode.cs +++ b/QRCoder.Core/Renderers/ArtQRCode.cs @@ -177,6 +177,7 @@ private SKBitmap RenderGraphicCore(int pixelsPerModule, SKColor darkSKColor, SKC if (pixelSizeFactor > 1) throw new ArgumentOutOfRangeException(nameof(pixelSizeFactor), "The parameter pixelSizeFactor must be between 0 and 1. (0-100%)"); int pixelSize = (int)Math.Min(pixelsPerModule, Math.Floor(pixelsPerModule / pixelSizeFactor)); + float pixelsPerModuleF = pixelsPerModule; var numModules = QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8); var offset = (drawQuietZones ? 0 : 4); @@ -208,10 +209,11 @@ private SKBitmap RenderGraphicCore(int pixelsPerModule, SKColor darkSKColor, SKC else if (backgroundImageStyle == BackgroundImageStyle.DataAreaOnly) { var bgOffset = 4 - offset; - using (var resizedImage = Resize(backgroundImage, size - (2 * bgOffset * pixelsPerModule))) + var dataAreaSize = size - (int)(2f * bgOffset * pixelsPerModule); + using (var resizedImage = Resize(backgroundImage, dataAreaSize)) { if (resizedImage != null) - graphics.DrawBitmap(resizedImage, 0 + (bgOffset * pixelsPerModule), (bgOffset * pixelsPerModule)); + graphics.DrawBitmap(resizedImage, (float)bgOffset * pixelsPerModule, (float)bgOffset * pixelsPerModule); graphics.Flush(); } } @@ -224,7 +226,7 @@ private SKBitmap RenderGraphicCore(int pixelsPerModule, SKColor darkSKColor, SKC { for (var y = 0; y < numModules; y += 1) { - var rectangleF = new SKRect(x * pixelsPerModule, y * pixelsPerModule, (x + 1) * pixelsPerModule, (y + 1) * pixelsPerModule); + var rectangleF = new SKRect(x * pixelsPerModuleF, y * pixelsPerModuleF, (x + 1) * pixelsPerModuleF, (y + 1) * pixelsPerModuleF); var pixelIsDark = this.QrCodeData.ModuleMatrix[offset + y][offset + x]; var solidBrush = pixelIsDark ? darkBrush : lightBrush; diff --git a/QRCoder.Core/Renderers/QRCode.cs b/QRCoder.Core/Renderers/QRCode.cs index 5e598ff..1d620b5 100644 --- a/QRCoder.Core/Renderers/QRCode.cs +++ b/QRCoder.Core/Renderers/QRCode.cs @@ -216,11 +216,11 @@ private SKBitmap RenderGraphic(int pixelsPerModule, SKColor darkSKColor, SKColor private static void DrawIcon(SKCanvas gfx, SKBitmap bmp, SKBitmap icon, int iconSizePercent, int iconBorderWidth, SKColor? iconBackgroundSKColor, SKPaint lightBrush) { - float iconDestWidth = iconSizePercent * bmp.Width / 100f; - float iconDestHeight = iconDestWidth * icon.Height / icon.Width; - float iconX = (bmp.Width - iconDestWidth) / 2; - float iconY = (bmp.Height - iconDestHeight) / 2; - var centerDest = new SKRect(iconX - iconBorderWidth, iconY - iconBorderWidth, iconX - iconBorderWidth + iconDestWidth + iconBorderWidth * 2, iconY - iconBorderWidth + iconDestHeight + iconBorderWidth * 2); + float iconDestWidth = iconSizePercent * (float)bmp.Width / 100f; + float iconDestHeight = iconDestWidth * (float)icon.Height / (float)icon.Width; + float iconX = ((float)bmp.Width - iconDestWidth) / 2; + float iconY = ((float)bmp.Height - iconDestHeight) / 2; + var centerDest = new SKRect(iconX - iconBorderWidth, iconY - iconBorderWidth, iconX - iconBorderWidth + iconDestWidth + iconBorderWidth * 2f, iconY - iconBorderWidth + iconDestHeight + iconBorderWidth * 2f); var iconDestRect = new SKRect(iconX, iconY, iconX + iconDestWidth, iconY + iconDestHeight); using (var iconBgBrush = iconBackgroundSKColor != null ? new SKPaint { Color = (SKColor)iconBackgroundSKColor } : null) { diff --git a/QRCoder.Core/Renderers/SvgQRCode.cs b/QRCoder.Core/Renderers/SvgQRCode.cs index 8a2ec94..9446884 100644 --- a/QRCoder.Core/Renderers/SvgQRCode.cs +++ b/QRCoder.Core/Renderers/SvgQRCode.cs @@ -226,6 +226,9 @@ public string GetGraphic(Size viewBox, string darkSKColorHex, string lightSKColo private static bool IsBlockedByLogo(double x, double y, ImageAttributes? attr, double pixelPerModule) { + if (!attr.HasValue) + return false; + return x + pixelPerModule >= attr.Value.X && x <= attr.Value.X + attr.Value.Width && y + pixelPerModule >= attr.Value.Y && y <= attr.Value.Y + attr.Value.Height; }