Skip to content

Conversation

@Shane32
Copy link
Owner

@Shane32 Shane32 commented Oct 19, 2025

Removed constructor:

  • public SvgLogo(System.Drawing.Bitmap iconRasterized, int iconSizePercent = 15, bool fillLogoBackground = true) { }.

Users will need to use the constructor with a byte[] containing a PNG image, or the one with a string containing a SVG icon.

Removed method from Base64QRCode:

  • public string GetGraphic(int pixelsPerModule, System.Drawing.Color darkColor, System.Drawing.Color lightColor, System.Drawing.Bitmap icon, int iconSizePercent = 15, int iconBorderWidth = 6, bool drawQuietZones = true, QRCoder.Base64QRCode.ImageType imgType = 2) { }

Users will need to use a different renderer and convert the resulting byte array via Convert.ToBase64String

Summary by CodeRabbit

  • New Features

    • Added HTML hex color support for QR code customization
    • Introduced Windows-specific QR code rendering capabilities with advanced styling options
    • Added color translation utilities for HTML color format support
  • Deprecation

    • Non-PNG formats deprecated in Base64 QR code generation; only PNG is now supported
  • Breaking Changes

    • Removed Bitmap-based logo constructor from SvgLogo
    • Reorganized System.Drawing-dependent APIs into separate project

Removed branch specification for pull request trigger.
…yload handling

- Implemented abstract class AbstractQRCode and derived classes: ArtQRCode, AsciiQRCode, Base64QRCode, BitmapByteQRCode, PdfByteQRCode, PngByteQRCode, PostscriptQRCode, SvgQRCode, and QRCode.
- Added helper classes for each QR code type to facilitate QR code generation.
- Introduced PayloadGenerator with various payload types including BezahlCode, BitcoinAddress, CalendarEvent, ContactData, Geolocation, Girocode, and more.
- Defined enums for various configurations and options within the QR code generation process.
- Included exception handling classes for managing errors related to data size and specific payload types.
- Established a comprehensive structure for QR code data management with QRCodeData and QRCodeGenerator classes.
@Shane32 Shane32 added this to the 2.0.0 milestone Oct 19, 2025
@Shane32 Shane32 self-assigned this Oct 19, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 19, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

The PR reorganizes QRCoder into separate projects: a core library and a new QRCoder.SystemDrawing project for System.Drawing-dependent code. It removes System.Drawing dependencies from the main project, moves QRCode/ArtQRCode classes to SystemDrawing, restricts Base64QRCode to PNG-only output, and updates test/benchmark projects accordingly.

Changes

Cohort / File(s) Summary
Project structure & solution
QRCoder.sln, QRCoder.SystemDrawing/QRCoder.SystemDrawing.csproj, QRCoder/QRCoder.csproj
Added new QRCoder.SystemDrawing project with multi-targeting (netstandard2.0, netstandard2.1, net6.0), conditional System.Drawing.Common references, and assembly signing. Removed System.Drawing.Common package references from main QRCoder.csproj. Updated solution configuration to include new project across all build platforms.
Core library refactoring
QRCoder/Base64QRCode.cs, QRCoder/PngByteQRCode.cs, QRCoder/Extensions/ColorTranslator.cs
Added PNG-only enforcement in Base64QRCode with obsolete ImageType overloads; introduced ColorTranslator extension for HTML color parsing; optimized PngByteQRCode to branch on default colors.
API surface removals
QRCoder/SvgQRCode.cs
Removed public Bitmap-based SvgLogo constructor.
Test project updates
QRCoderApiTests/QRCoderApiTests.csproj, QRCoderTests/QRCoderTests.csproj, QRCoderBenchmarks/QRCoderBenchmarks.csproj, QRCoderConsole/QRCoderConsole.csproj, QRCoderDemo/QRCoderDemo.csproj
Replaced project references from QRCoder to QRCoder.SystemDrawing.
Test logic updates
QRCoderTests/Base64QRCodeRendererTests.cs, QRCoderTests/SvgQRCodeRendererTests.cs, QRCoderApiTests/ApiApprovalTests.cs
Modified Base64QRCode JPEG test to expect NotSupportedException; removed five SVG PNG-logo Bitmap tests; added QRCode type to API coverage test.
API approval files
QRCoderApiTests/QRCoder.approved.txt, QRCoderApiTests/net60/QRCoder.approved.txt, QRCoderApiTests/net60/QRCoder.SystemDrawing.approved.txt, QRCoderApiTests/netstandard20+netstandard21/QRCoder.SystemDrawing.approved.txt
Removed QRCode, ArtQRCode, QRCodeHelper, and QRCodeData from main QRCoder API surface; added these classes to new QRCoder.SystemDrawing API surface for platform-specific rendering (Windows via SupportedOSPlatform).

Sequence Diagram

sequenceDiagram
    participant Consumer
    participant QRCoder as QRCoder<br/>(Core)
    participant SystemDrawing as QRCoder.SystemDrawing<br/>(System.Drawing)
    
    Consumer->>QRCoder: Generate QR data<br/>(QRCodeData, QRCodeGenerator)
    QRCoder->>Consumer: Return QRCodeData
    
    Consumer->>SystemDrawing: Create QRCode/ArtQRCode<br/>(Windows platform)
    SystemDrawing->>SystemDrawing: Call GetGraphic<br/>(Color, Bitmap)
    SystemDrawing->>Consumer: Return Bitmap
    
    Consumer->>QRCoder: Create Base64QRCode<br/>(PNG-only)
    QRCoder->>QRCoder: ColorTranslator.FromHtml<br/>(HTML hex → Color)
    QRCoder->>QRCoder: PngByteQRCode.GetGraphic<br/>(default black/white or custom)
    QRCoder->>Consumer: Return base64 PNG string
    
    Consumer->>SystemDrawing: Request non-PNG format<br/>(JPEG, GIF)
    SystemDrawing-->>Consumer: NotSupportedException
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

The review requires understanding a significant architectural split: moving System.Drawing-dependent code to a separate project, updating cross-cutting dependencies, verifying API surface changes across multiple approval files, and ensuring test coverage remains correct after the reorganization. Multiple file categories demand separate reasoning despite some homogeneous patterns (project reference updates).

Possibly related PRs

Suggested labels

refactoring

Suggested reviewers

  • gfoidl
  • codebude

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "Split QRCode and ArtQRCode to QRCoder.SystemDrawing" accurately and directly describes the primary change in the changeset. The PR creates a new project called QRCoder.SystemDrawing, moves the QRCode and ArtQRCode classes into it, updates all project references across the solution, and removes System.Drawing dependencies from the core QRCoder project. This architectural refactoring is the dominant theme throughout the changeset, including the creation of new approved API files for the reorganized structure. The title is specific, concise, and clearly conveys the intent without being vague or misleading.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Shane32 Shane32 requested a review from gfoidl October 19, 2025 03:01
@Shane32
Copy link
Owner Author

Shane32 commented Oct 19, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
QRCoder/PngByteQRCode.cs (1)

54-56: Make the default-color fast path robust to Color naming.

Comparing System.Drawing.Color with == can be tripped by named vs custom colors. Compare ARGB to be explicit.

Apply:

-        => darkColor == System.Drawing.Color.Black && lightColor == System.Drawing.Color.White
+        => darkColor.ToArgb() == System.Drawing.Color.Black.ToArgb() 
+           && lightColor.ToArgb() == System.Drawing.Color.White.ToArgb()
             ? GetGraphic(pixelsPerModule, drawQuietZones)
             : GetGraphic(pixelsPerModule, [darkColor.R, darkColor.G, darkColor.B, darkColor.A], [lightColor.R, lightColor.G, lightColor.B, lightColor.A], drawQuietZones);
QRCoder.SystemDrawing/QRCoder.SystemDrawing.csproj (1)

3-15: Declare Windows support and enable Windows targeting for non-Windows builds.

System.Drawing.Common is only supported on Windows in .NET 6+. Mark the package/platform to avoid CA1416 warnings and runtime surprises when consumers use this library cross‑platform.

Consider:

   <PropertyGroup>
     <TargetFrameworks>netstandard2.0;netstandard2.1;net6.0</TargetFrameworks>
     <IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">true</IsTrimmable>
     <IsPackable>true</IsPackable>
+    <SupportedOSPlatform>windows</SupportedOSPlatform>
+    <EnableWindowsTargeting>true</EnableWindowsTargeting>
   </PropertyGroup>

Optionally add assembly-level attributes for APIs in this project:

  • [assembly: System.Runtime.Versioning.SupportedOSPlatform("windows")]

Also applies to: 17-26

QRCoderTests/Base64QRCodeRendererTests.cs (1)

46-56: Loosen assertion to message casing/wording changes.

Exception text can vary. Assert case‑insensitively or match enum/name to reduce brittleness.

Example:

-        ex.Message.ShouldContain("Only PNG format is supported");
-        ex.Message.ShouldContain("Jpeg");
+        ex.Message.ShouldContain("Only PNG format is supported", Case.Insensitive);
+        ex.Message.ShouldContain(nameof(Base64QRCode.ImageType.Jpeg), Case.Insensitive);
QRCoder/Base64QRCode.cs (1)

45-46: Consider input validation for HTML hex color strings.

ColorTranslator.FromHtml will throw an ArgumentException if the color string is invalid. Consider adding validation or wrapping the call in a try-catch to provide clearer error messages to users.

Example:

 public string GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex, bool drawQuietZones = true)
-    => GetGraphic(pixelsPerModule, ColorTranslator.FromHtml(darkColorHtmlHex), ColorTranslator.FromHtml(lightColorHtmlHex), drawQuietZones);
+{
+    if (string.IsNullOrWhiteSpace(darkColorHtmlHex))
+        throw new ArgumentException("Dark color cannot be null or empty.", nameof(darkColorHtmlHex));
+    if (string.IsNullOrWhiteSpace(lightColorHtmlHex))
+        throw new ArgumentException("Light color cannot be null or empty.", nameof(lightColorHtmlHex));
+    
+    try
+    {
+        return GetGraphic(pixelsPerModule, ColorTranslator.FromHtml(darkColorHtmlHex), ColorTranslator.FromHtml(lightColorHtmlHex), drawQuietZones);
+    }
+    catch (Exception ex) when (ex is ArgumentException or FormatException)
+    {
+        throw new ArgumentException($"Invalid color format. Expected HTML hex format (e.g., '#FF0000'). Dark: '{darkColorHtmlHex}', Light: '{lightColorHtmlHex}'", ex);
+    }
+}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6b1ca5 and ec94c43.

⛔ Files ignored due to path filters (7)
  • QRCoderTests/Base64QRCodeRendererTests.can_render_base64_qrcode_jpeg.approved.gif is excluded by !**/*.gif
  • QRCoderTests/SvgQRCodeRendererTests.can_render_svg_qrcode_with_png_logo_bitmap.approved.svg is excluded by !**/*.svg
  • QRCoderTests/SvgQRCodeRendererTests.can_render_svg_qrcode_with_png_logo_bitmap.embeddedLogo.approved.gif is excluded by !**/*.gif
  • QRCoderTests/SvgQRCodeRendererTests.can_render_svg_qrcode_with_png_logo_bitmap_without_background.approved.svg is excluded by !**/*.svg
  • QRCoderTests/SvgQRCodeRendererTests.can_render_svg_qrcode_with_png_logo_bitmap_without_background.embeddedLogo.approved.gif is excluded by !**/*.gif
  • QRCoderTests/SvgQRCodeRendererTests.can_render_svg_qrcode_with_png_logo_bitmap_without_quietzones.approved.svg is excluded by !**/*.svg
  • QRCoderTests/SvgQRCodeRendererTests.can_render_svg_qrcode_with_png_logo_bitmap_without_quietzones.embeddedLogo.approved.gif is excluded by !**/*.gif
📒 Files selected for processing (19)
  • QRCoder.SystemDrawing/QRCoder.SystemDrawing.csproj (1 hunks)
  • QRCoder.sln (2 hunks)
  • QRCoder/Base64QRCode.cs (4 hunks)
  • QRCoder/Extensions/ColorTranslator.cs (1 hunks)
  • QRCoder/PngByteQRCode.cs (1 hunks)
  • QRCoder/QRCoder.csproj (0 hunks)
  • QRCoder/SvgQRCode.cs (0 hunks)
  • QRCoderApiTests/ApiApprovalTests.cs (1 hunks)
  • QRCoderApiTests/QRCoder.approved.txt (2 hunks)
  • QRCoderApiTests/QRCoderApiTests.csproj (1 hunks)
  • QRCoderApiTests/net60/QRCoder.SystemDrawing.approved.txt (1 hunks)
  • QRCoderApiTests/net60/QRCoder.approved.txt (0 hunks)
  • QRCoderApiTests/netstandard20+netstandard21/QRCoder.SystemDrawing.approved.txt (1 hunks)
  • QRCoderBenchmarks/QRCoderBenchmarks.csproj (1 hunks)
  • QRCoderConsole/QRCoderConsole.csproj (1 hunks)
  • QRCoderDemo/QRCoderDemo.csproj (1 hunks)
  • QRCoderTests/Base64QRCodeRendererTests.cs (1 hunks)
  • QRCoderTests/QRCoderTests.csproj (1 hunks)
  • QRCoderTests/SvgQRCodeRendererTests.cs (0 hunks)
💤 Files with no reviewable changes (4)
  • QRCoderTests/SvgQRCodeRendererTests.cs
  • QRCoder/SvgQRCode.cs
  • QRCoder/QRCoder.csproj
  • QRCoderApiTests/net60/QRCoder.approved.txt
🔇 Additional comments (14)
QRCoder.sln (1)

34-35: LGTM! New project properly integrated into solution.

The QRCoder.SystemDrawing project is correctly added with:

  • Proper project GUID ({FEE6DC1D-BE5A-4498-A70D-35C516AD13F3})
  • Complete build configurations for all platforms (Any CPU, ARM, x64, x86)
  • Both Debug and Release configurations with ActiveCfg and Build.0 entries

Also applies to: 206-221

QRCoderApiTests/netstandard20+netstandard21/QRCoder.SystemDrawing.approved.txt (1)

1-54: LGTM! Well-structured API surface for System.Drawing integration.

The public API is clean and follows consistent patterns:

  • Proper inheritance from AbstractQRCode and IDisposable
  • Helper classes for simplified usage
  • Reasonable default parameters
  • Maintains QRCoder namespace for compatibility
QRCoderApiTests/QRCoderApiTests.csproj (1)

9-9: LGTM! Project reference correctly updated.

The reference change from QRCoder to QRCoder.SystemDrawing aligns with the PR objectives and enables testing of the new System.Drawing-based API surface.

QRCoderApiTests/ApiApprovalTests.cs (1)

47-47: LGTM! Proper test coverage for QRCode API surface.

Adding the QRCode type to the API approval tests ensures that any changes to the public API of the System.Drawing-based QRCode class are tracked and reviewed.

QRCoderBenchmarks/QRCoderBenchmarks.csproj (1)

16-16: LGTM! Benchmarks correctly reference SystemDrawing.

The project reference update ensures benchmarks can measure performance of the System.Drawing-based QR code rendering.

QRCoderTests/QRCoderTests.csproj (1)

43-43: LGTM! Test project correctly updated to reference SystemDrawing.

The reference change enables testing of the System.Drawing-based QR code functionality while maintaining multi-target framework support.

QRCoderDemo/QRCoderDemo.csproj (1)

19-21: LGTM! Demo project simplified and updated correctly.

The project reference has been updated to use QRCoder.SystemDrawing with a cleaner, simplified reference format (removing unnecessary GUID and Name metadata).

QRCoderConsole/QRCoderConsole.csproj (1)

31-31: LGTM! Console project correctly references SystemDrawing.

The reference update aligns with the PR objectives. Note that the project targets both Windows-specific (net6.0-windows) and cross-platform (net6.0) frameworks, which may rely on different rendering paths.

QRCoder/Extensions/ColorTranslator.cs (1)

9-221: Solid fallback for HTML color parsing.

Named/hex parsing looks correct and defensive. Guard + dictionary approach LGTM.

QRCoderApiTests/QRCoder.approved.txt (1)

33-41: API delta aligns with PNG‑only path and obsoleted imgType.

Obsolete messages and overload shape look consistent with the new behavior.

Also applies to: 51-55

QRCoder/Base64QRCode.cs (3)

57-59: LGTM! Clear deprecation path.

The obsolete attribute provides a clear migration message, and the delegation chain ensures consistent behavior.


70-79: LGTM! Appropriate handling of the breaking change.

The method correctly throws NotSupportedException for non-PNG formats while still supporting existing code that explicitly specifies PNG format. The obsolete attribute guides users to the new API.


122-142: LGTM! Well-implemented convenience method.

The method properly disposes of all resources using using statements and provides a clean, single-call API for generating base64-encoded QR codes.

QRCoderApiTests/net60/QRCoder.SystemDrawing.approved.txt (1)

1-58: LGTM! Well-structured API surface for Windows-specific System.Drawing support.

The API approval file correctly documents the public surface of the QRCoder.SystemDrawing assembly:

  • All types are appropriately marked with [SupportedOSPlatform("windows")] since System.Drawing.Bitmap is Windows-specific in .NET 6+
  • The API follows consistent naming conventions and patterns
  • Both QRCode and ArtQRCode classes include corresponding helper classes for single-call convenience methods
  • The enums are properly nested within their respective classes

This separation successfully isolates System.Drawing dependencies as intended by the PR.

@Shane32 Shane32 added the breaking Breaking changes label Oct 19, 2025
Copy link
Collaborator

@gfoidl gfoidl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few nits, otherwise LGTM.

@Shane32
Copy link
Owner Author

Shane32 commented Oct 25, 2025

There's a newline at the bottom of QRCoderConsole.csproj and QRCoderDemo.csproj. Let me know if you were referring to something else.

@gfoidl
Copy link
Collaborator

gfoidl commented Oct 25, 2025

GitHub diff here showed me that the newline is missing. When you there's one, then it's OK.

@Shane32
Copy link
Owner Author

Shane32 commented Oct 25, 2025

GitHub diff here showed me that the newline is missing. When you there's one, then it's OK.

Actually, you're right. I don't know why GitHub didn't show me the missing newlines. I have their beta expierence enabled; perhaps that's why it's not showing up for me, but did for you. 🤷‍♂️

Base automatically changed from tfm to develop October 25, 2025 23:52
@Shane32 Shane32 merged commit 7bccc6c into develop Oct 26, 2025
6 checks passed
@Shane32 Shane32 deleted the systemdrawing branch October 26, 2025 00:02
@gfoidl
Copy link
Collaborator

gfoidl commented Oct 26, 2025

I have their beta expierence enabled

I have it also enabled. Maybe some other preview feature that shows it differently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants