# How to Use IronQR with Claude Code
The marketing team requires each campaign QR code to use the brand's navy color, feature the logo in the center, and be available in both poster and sticker sizes. However, each additional styling choice can reduce scan reliability. For example, a logo may obscure modules, a light foreground can lower contrast, and smaller print sizes reduce pixel density. A QR code may appear correct on screen but still fail in real-world use. Claude Code, Anthropic's coding agent, operates across terminals, VS Code, JetBrains, desktop applications, and the web. In any environment, it reads the project, edits files, and runs commands, so it can render styled codes, decode saved files, and adjust styling until the payload is preserved.
IronQR generates and reads QR codes within the same .NET process, so the agent can scan after each change. The library automatically rejects some unreadable designs. A manually sized logo that covers too much, or a foreground color too close to a white background, triggers an IronQrException when saving. Other styling choices may save successfully but still fail to decode later. The most reliable approach is to test a matrix of styled variants and decode each saved PNG. This guide explains how to configure Claude Code for this process, with three tested prompts and the IronQR behavior each one depends on.
A single model setting supports all three prompts. The `opusplan` alias uses Opus in plan mode and Sonnet otherwise, which suits a session where only the matrix build requires planning.
*as-heading:2(Quickstart)*
!!!--LIBRARY_NUGET_INSTALL_BLOCK--!!!
Open the project folder in a terminal, start Claude Code, and run `/model opusplan`. Type `@` before a file path to hand Claude Code that file, then send the request.
```text
Install IronQR from NuGet here and make one branded QR code for the
spring-sale campaign in @Brand/campaigns.json. Use that entry's URL,
foreground color, and background color, put @Brand/logo.png in the center,
and save the result as out/spring-sale.png. Print the saved image's width
and height in pixels first, then open the file again with QrReader and print
the decoded text and whether it equals the campaign URL. The license key is
in the IRONQR_LICENSE_KEY environment variable.
```
The most direct version of this code can fail. In our probes, the spring-sale code at the default error correction level with an automatically sized logo saved without error, then read back empty or threw ObjectDisposedException in the reader's default scan mode. A manual 100-pixel logo on a 500-pixel code read back correctly.
Check the printed width first. In our probe, styling options with no size set produced a 49-pixel image for this URL.
<div class="hsg-featured-snippet">
<h3>Minimal Workflow (5 steps)</h3>
<ol>
<li><a class="js-modal-open" data-modal-id="trial-license-after-download" href="https://www.nuget.org/packages/IronQR/">Download the C# QR code library from NuGet</a></li>
<li>Start Claude Code in the project folder and choose a model with <code>/model</code></li>
<li>Record the IronQR styling rules in <code>CLAUDE.md</code> so each session starts with them</li>
<li>Describe every variant to render, from correction level and logo size to colors and pixel size</li>
<li>Decode each saved PNG in both scan modes</li>
</ol>
</div>
<br class="clear" />
---
## What does Claude Code do in a .NET QR code project?
The agent writes the renderer, reads the brand file, saves one PNG per variant, decodes each file, and reports which designs hold up. You say which variants the campaign needs and review the table that comes back.
Branded codes make that check worth automating, because logo size, correction level and pixel size interact. In the tested run, IronQR saved a manual logo at 30 percent of the width on a 600-pixel code and refused the same proportion at 120 pixels for one campaign, and another campaign showed the reverse.
Name IronQR as the only QR library from the first prompt. An agent that guesses a package name can install a look-alike published to catch that guess, an attack called *slopsquatting*.
## How do you set up Claude Code?
Install Claude Code with Anthropic's [quickstart](https://code.claude.com/docs/en/quickstart) and sign in. When it starts in a terminal and replies, it is ready.
## How do you set up a project Claude Code can work in?
Prepare the repository before the first prompt. A .NET 9 console project that builds, a `Brand/campaigns.json` file with each campaign's URL and colors, and the logo files give the agent real inputs to work from. Start Claude Code from that folder so the session is scoped to it.
Claude Code reads `CLAUDE.md` at the start of every session, which makes it the place for rules that should outlive one prompt. Once the Quickstart has added the package, a second prompt writes the file.
```text
Write CLAUDE.md in the repository root with a section called QR codes. It
should tell every later session that IronQR (NuGet package IronQR, pinned to
the version now in BrandQr.csproj, namespaces IronQr and IronQr.Enum) is the
only QR library allowed here; that IronQR member names are checked against
IronQr.xml inside the ironqr.slim folder of the local NuGet cache before use;
that QrStyleOptions is always given an explicit Dimensions and Margins; that
the key comes only from IRONQR_LICENSE_KEY at startup and is never written to
a file or printed; and that a QR image counts as finished only after the saved
PNG has been decoded back to its exact payload.
```
The XML path matters because the styling and reading types ship in the `IronQR.Slim` package, which `IronQR` depends on, so the member list sits in that folder of the cache. For guides beyond the [member list](https://ironsoftware.com/qr/csharp/object-reference/api/), IronQR publishes an index for agents at [`llms.txt`](https://ironsoftware.com/qr/csharp/llms.txt).
Handle the license before the first render. With no key, both `QrWriter.Write` and `QrReader.Read` throw a LicensingException whose message reads "Production License Required", and there is no watermarked trial output to fall back on. That exception type is not public, so have the program check `License.IsLicensed` after setting the key from `IRONQR_LICENSE_KEY` instead of catching the exception by name. The [IronQR License Keys](https://ironsoftware.com/qr/csharp/get-started/license-keys/) page covers getting a key and the places IronQR reads it from.
## Which IronQR settings belong in CLAUDE.md?
Each line was checked against IronQR 2026.10.1 by building a probe or by running one with a licensed key. Paste the block under the QR codes section.
```markdown
## QR codes: IronQR 2026.10.1 behavior
- new QrStyleOptions { ... } starts at Dimensions 0 and margins 0, which
renders one pixel per module. The constructor with arguments defaults to
300 and 10. Always set both.
- Margins are added outside Dimensions. Dimensions 600 with Margins 24
saves a 648 x 648 PNG. Margins has no getter, so read MarginTop and the
other sides.
- QrErrorCorrectionLevel.High is level Q (about 25 percent) and Highest is
level H (about 30 percent). QrWriter.Write without options uses Highest.
- Build QrOptions with its constructor. An object initializer leaves
Encoding at None, and Write throws IronQrEncodingException.
- QrLogo width and height 0 let IronQR choose the logo size. A manual size
it cannot read back throws IronQrException from Save.
- Save checks a changed foreground color. It does not check a changed
background color.
- qr.Verify(expected) takes the expected text, not a file path.
- Save(style) keeps the style on the QrCode, so a later Save() repeats it.
- Do not put QrImageInput in a using block. Its explicit IDisposable.Dispose
throws NotImplementedException after a successful read. Its public
Dispose() works.
- Read every saved PNG with QrScanMode.Auto and QrScanMode.OnlyBasicScan.
```
Black modules on a black background saved without an exception, and neither scan mode could decode the file.
## How do you control the size, margins and colors of a QR code?
One `QrStyleOptions` object holds every visual choice. `Save` applies it and returns a bitmap you write to disk with `SaveAs`. The error correction level is the one setting that lives elsewhere, in `QrOptions`, because it changes the encoded symbol itself.
`Dimensions` sets the code size in pixels and `Margins` the quiet zone on all four sides, while `MarginTop` and the other sides set one side each. `Color` paints the dark modules and `BackgroundColor` the light area and margins. `Logo` takes a `QrLogo` with the bitmap, width, height and corner radius.
In our probe, a 400-pixel code with 50-pixel top and bottom margins and 20-pixel side margins saved at 440 x 500. The [resize guide](https://ironsoftware.com/qr/csharp/how-to/resize-qr-code-image/), the [margins guide](https://ironsoftware.com/qr/csharp/how-to/add-margins-qr-code/), and the [colors guide](https://ironsoftware.com/qr/csharp/how-to/implement-custom-qr-code-colors/) show each setting on its own.
[[i:(Calling `Save` with no argument on a code that has never been styled returns a 250 x 250 image. That size is an internal default.)]]
## How large can a logo be at each error correction level?
Smaller than the correction percentages suggest. Those figures count the codewords Reed-Solomon decoding can rebuild, and a central logo is only one source of damage. We rendered the spring-sale URL at 600 pixels with a plain square logo, let IronQR size it automatically, and then raised a manual size one percent at a time until IronQR refused to save it.
| Level | Documented recovery | Automatic logo (width, area) | Largest manual logo (width, area) |
|---|---|---|---|
| Low | 7% | 20%, 4.0% | 23%, 5.3% |
| Medium | 15% | 30%, 9.0% | 31%, 9.6% |
| High | 25% | 32.5%, 10.6% | 39%, 15.2% |
| Highest | 30% | 32%, 10.2% | 44%, 19.4% |
In the 2026.10.1 assembly, automatic sizing tries a short list of fractions of the code width, from one half down to one twentieth, and keeps the first one its reader decodes. That list explains why High and Highest land near one third of the width. A manual size goes higher, to between about 60 and 75 percent of the documented recovery by area, but IronQR checks it with its own reader at full resolution. A second scan mode can still fail where that check passed.
The figures depend on the payload. A longer URL produces a denser symbol with different limits, so treat the table as the shape of the trade-off and let the matrix measure your own campaigns.
## How do you test every styled IronQR variant in one prompt?
Ask for the whole grid in one prompt and let plan mode settle the design first. Press Shift+Tab until the status bar shows plan mode, then send the prompt.
```text
Build Services/BrandedQrRenderer.cs, which renders one campaign from
@Brand/campaigns.json for a given QrErrorCorrectionLevel, logo mode, and
pixel size, and Services/ScanMatrix.cs, which renders every campaign at every
correction level (Low, Medium, High, Highest), with three logo modes (no
logo, a QrLogo of width and height 0 so IronQR sizes it, and a manual logo 30
percent of Dimensions wide that keeps the logo's aspect ratio), at the poster
and sticker sizes in the JSON. Call the matrix from Program.cs after the
spring-sale code. Save each PNG under out/matrix/. Decode every saved file
twice with a new QrReader each time, once with QrScanMode.Auto and once with
QrScanMode.OnlyBasicScan, and catch exceptions per file, including any that
Save throws. Write out/scan-matrix.csv with campaign, level, logo mode, size,
image width and height, the save result, and both read results, then print
how many variants decode to the exact URL in both modes. When the matrix has
run, have the general-purpose subagent check every IronQR member in the new
files against IronQr.xml and list any it cannot find.
```
Each clause closes a way the results could look better than they are.
1. **Every combination is named:** three campaigns, four levels, three logo modes, and two sizes make 72 variants, so a missing row in `out/scan-matrix.csv` is visible.
2. **Save failures are rows:** a refused save is a result, and those rows show where the logo size limit sits.
3. **A fresh reader for each read:** one failing read cannot affect the next.
4. **A second agent checks the API:** the general-purpose subagent loads `CLAUDE.md`, which the built-in Explore and Plan subagents skip, so the check sees the project's rules.
[[t:(Approve the plan only after it lists every variant and shows a try block around each one.)]]
## What should you verify before trusting generated IronQR code?
`QrScanMode.Auto` falls back to the basic scan only when its detection model finds nothing, and the enum's own documentation describes it as the detection model first, then "a basic brute-force read if none are found". When the model finds the code but cannot decode it, Auto returns an empty result and the basic scan never runs.
The basic scan decoded every Quickstart variant that failed above, and the exception comes from inside IronQR 2026.10.1. In our calibration run of the full matrix, every file Auto missed had a logo, and six of the eight were at High or Highest, the two levels with the most redundancy to spend on a logo. In the tested run, with a flat 10-pixel margin the agent chose, two of the eight Auto misses had no logo at all.
Add these checks to the same review.
- **The build:** an invented member fails `dotnet build`, and so does a using directive spelled `IronQR`, which uses the package's casing while the namespace is `IronQr`.
- **The sizes:** compare each saved width with the requested size plus both side margins. A mismatch shows a style that never reached the save call.
- **The payload:** decode the file on disk. `Verify` compares text with IronQR's own in-memory rendering, so a file path returns false and a file written with the wrong style goes unnoticed.
The [checksum and fault tolerance guide](https://ironsoftware.com/qr/csharp/how-to/checksum-and-fault-tolerance/) covers reading damaged codes and validating what comes back. For a complete IronQR task run end to end with its own pass criteria, see the [AI coding assistants guide](https://ironsoftware.com/qr/csharp/ai-agents/ai/).
## What did the prompts produce in a real run?
We sent the three prompts above to Claude Code in order, in one session. The brand file held three campaigns, a 600-pixel poster size and a 120-pixel sticker size, beside a square logo and a wide wordmark. A separate Release build of a clean copy then reran the matrix and wrote an identical CSV, and an independent decode of every saved PNG agreed with each row.
- On its first run the matrix matched 0 of 72 variants in both modes. After Claude Code removed the using block on `QrImageInput`, 55 of 72 matched.
- IronQR refused 9 variants at save, every one with the manual logo. Of the 63 files it saved, the basic scan decoded all 63 and Auto decoded 55.
- For the Quickstart, Claude Code chose a 300-pixel code with 10-pixel margins and a 50 x 50 logo. Its 320 x 320 PNG matched the URL on the first read.
- The subagent found no IronQR member missing from `IronQr.xml`.
- Every prompt left a clean Release build with no hand edits, and the matrix totals equal the calibration run.
- A typed reply approved the third prompt's plan in place of the plan dialog, because the session ran non-interactively.
Versions, models, timings and the test machine for this guide and its siblings sit in the shared [run record](/qr/csharp/ai-agents/ai/#the-run-record).
---
## Troubleshooting
- [Apply a License Key in IronQR](https://ironsoftware.com/qr/csharp/troubleshooting/apply-a-license-key-in-ironqr/) if the build succeeds and the first write throws a licensing exception
- [Add a Logo to QR Codes](https://ironsoftware.com/qr/csharp/how-to/add-custom-logo-qr-code/) if saving a manually sized logo throws IronQrException
- [Set QR Code Error Correction Levels](https://ironsoftware.com/qr/csharp/how-to/error-correction-qr-code/) if a variant needs more redundancy for its logo
---
## Questions?
If you have any questions, reach out to [support@ironsoftware.com](mailto:support@ironsoftware.com)
The marketing team requires each campaign QR code to use the brand's navy color, feature the logo in the center, and be available in both poster and sticker sizes. However, each additional styling choice can reduce scan reliability. For example, a logo may obscure modules, a light foreground can lower contrast, and smaller print sizes reduce pixel density. A QR code may appear correct on screen but still fail in real-world use. Claude Code, Anthropic's coding agent, operates across terminals, VS Code, JetBrains, desktop applications, and the web. In any environment, it reads the project, edits files, and runs commands, so it can render styled codes, decode saved files, and adjust styling until the payload is preserved.
IronQR generates and reads QR codes within the same .NET process, so the agent can scan after each change. The library automatically rejects some unreadable designs. A manually sized logo that covers too much, or a foreground color too close to a white background, triggers an IronQrException when saving. Other styling choices may save successfully but still fail to decode later. The most reliable approach is to test a matrix of styled variants and decode each saved PNG. This guide explains how to configure Claude Code for this process, with three tested prompts and the IronQR behavior each one depends on.
A single model setting supports all three prompts. The opusplan alias uses Opus in plan mode and Sonnet otherwise, which suits a session where only the matrix build requires planning.
Quickstart
Install with NuGet
PM > Install-Package IronQR
Install-Package IronQR
Install IronQR by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.
Open the project folder in a terminal, start Claude Code, and run /model opusplan. Type @ before a file path to hand Claude Code that file, then send the request.
Install IronQR from NuGet here and make one branded QR code for thespring-sale campaign in @Brand/campaigns.json. Use that entry's URL,foreground color, and background color, put @Brand/logo.png in the center,and save the result as out/spring-sale.png. Print the saved image's widthand height in pixels first, then open the file again with QrReader and printthe decoded text and whether it equals the campaign URL. The license key isin the IRONQR_LICENSE_KEY environment variable.
Install IronQR from NuGet here and make one branded QR code for the
spring-sale campaign in @Brand/campaigns.json. Use that entry's URL,
foreground color, and background color, put @Brand/logo.png in the center,
and save the result as out/spring-sale.png. Print the saved image's width
and height in pixels first, then open the file again with QrReader and print
the decoded text and whether it equals the campaign URL. The license key is
in the IRONQR_LICENSE_KEY environment variable.
Text
The most direct version of this code can fail. In our probes, the spring-sale code at the default error correction level with an automatically sized logo saved without error, then read back empty or threw ObjectDisposedException in the reader's default scan mode. A manual 100-pixel logo on a 500-pixel code read back correctly.
Check the printed width first. In our probe, styling options with no size set produced a 49-pixel image for this URL.
Start Claude Code in the project folder and choose a model with /model
Record the IronQR styling rules in CLAUDE.md so each session starts with them
Describe every variant to render, from correction level and logo size to colors and pixel size
Decode each saved PNG in both scan modes
What does Claude Code do in a .NET QR code project?
The agent writes the renderer, reads the brand file, saves one PNG per variant, decodes each file, and reports which designs hold up. You say which variants the campaign needs and review the table that comes back.
Branded codes make that check worth automating, because logo size, correction level and pixel size interact. In the tested run, IronQR saved a manual logo at 30 percent of the width on a 600-pixel code and refused the same proportion at 120 pixels for one campaign, and another campaign showed the reverse.
Name IronQR as the only QR library from the first prompt. An agent that guesses a package name can install a look-alike published to catch that guess, an attack called slopsquatting.
How do you set up Claude Code?
Install Claude Code with Anthropic's quickstart and sign in. When it starts in a terminal and replies, it is ready.
How do you set up a project Claude Code can work in?
Prepare the repository before the first prompt. A .NET 9 console project that builds, a Brand/campaigns.json file with each campaign's URL and colors, and the logo files give the agent real inputs to work from. Start Claude Code from that folder so the session is scoped to it.
Claude Code reads CLAUDE.md at the start of every session, which makes it the place for rules that should outlive one prompt. Once the Quickstart has added the package, a second prompt writes the file.
Write CLAUDE.md in the repository root with a section called QR codes. Itshould tell every later session that IronQR (NuGet package IronQR, pinned tothe version now in BrandQr.csproj, namespaces IronQr and IronQr.Enum) is theonly QR library allowed here; that IronQR member names are checked againstIronQr.xml inside the ironqr.slim folder of the local NuGet cache before use;that QrStyleOptions is always given an explicit Dimensions and Margins; thatthe key comes only from IRONQR_LICENSE_KEY at startup and is never written toa file or printed; and that a QR image counts as finished only after the savedPNG has been decoded back to its exact payload.
Write CLAUDE.md in the repository root with a section called QR codes. It
should tell every later session that IronQR (NuGet package IronQR, pinned to
the version now in BrandQr.csproj, namespaces IronQr and IronQr.Enum) is the
only QR library allowed here; that IronQR member names are checked against
IronQr.xml inside the ironqr.slim folder of the local NuGet cache before use;
that QrStyleOptions is always given an explicit Dimensions and Margins; that
the key comes only from IRONQR_LICENSE_KEY at startup and is never written to
a file or printed; and that a QR image counts as finished only after the saved
PNG has been decoded back to its exact payload.
Text
The XML path matters because the styling and reading types ship in the IronQR.Slim package, which IronQR depends on, so the member list sits in that folder of the cache. For guides beyond the member list, IronQR publishes an index for agents at llms.txt.
Handle the license before the first render. With no key, both QrWriter.Write and QrReader.Read throw a LicensingException whose message reads "Production License Required", and there is no watermarked trial output to fall back on. That exception type is not public, so have the program check License.IsLicensed after setting the key from IRONQR_LICENSE_KEY instead of catching the exception by name. The IronQR License Keys page covers getting a key and the places IronQR reads it from.
Which IronQR settings belong in CLAUDE.md?
Each line was checked against IronQR 2026.10.1 by building a probe or by running one with a licensed key. Paste the block under the QR codes section.
## QR codes: IronQR 2026.10.1 behavior- new QrStyleOptions { ... } starts at Dimensions 0 and margins 0, which renders one pixel per module. The constructor with arguments defaults to 300 and 10. Always set both.- Margins are added outside Dimensions. Dimensions 600 with Margins 24 saves a 648 x 648 PNG. Margins has no getter, so read MarginTop and the other sides.- QrErrorCorrectionLevel.High is level Q (about 25 percent) and Highest is level H (about 30 percent). QrWriter.Write without options uses Highest.- Build QrOptions with its constructor. An object initializer leaves Encoding at None, and Write throws IronQrEncodingException.- QrLogo width and height 0 let IronQR choose the logo size. A manual size it cannot read back throws IronQrException from Save.- Save checks a changed foreground color. It does not check a changed background color.- qr.Verify(expected) takes the expected text, not a file path.- Save(style) keeps the style on the QrCode, so a later Save() repeats it.- Do not put QrImageInput in a using block. Its explicit IDisposable.Dispose throws NotImplementedException after a successful read. Its public Dispose() works.- Read every saved PNG with QrScanMode.Auto and QrScanMode.OnlyBasicScan.
## QR codes: IronQR 2026.10.1 behavior
- new QrStyleOptions { ... } starts at Dimensions 0 and margins 0, which
renders one pixel per module. The constructor with arguments defaults to
300 and 10. Always set both.
- Margins are added outside Dimensions. Dimensions 600 with Margins 24
saves a 648 x 648 PNG. Margins has no getter, so read MarginTop and the
other sides.
- QrErrorCorrectionLevel.High is level Q (about 25 percent) and Highest is
level H (about 30 percent). QrWriter.Write without options uses Highest.
- Build QrOptions with its constructor. An object initializer leaves
Encoding at None, and Write throws IronQrEncodingException.
- QrLogo width and height 0 let IronQR choose the logo size. A manual size
it cannot read back throws IronQrException from Save.
- Save checks a changed foreground color. It does not check a changed
background color.
- qr.Verify(expected) takes the expected text, not a file path.
- Save(style) keeps the style on the QrCode, so a later Save() repeats it.
- Do not put QrImageInput in a using block. Its explicit IDisposable.Dispose
throws NotImplementedException after a successful read. Its public
Dispose() works.
- Read every saved PNG with QrScanMode.Auto and QrScanMode.OnlyBasicScan.
Text
Black modules on a black background saved without an exception, and neither scan mode could decode the file.
How do you control the size, margins and colors of a QR code?
One QrStyleOptions object holds every visual choice. Save applies it and returns a bitmap you write to disk with SaveAs. The error correction level is the one setting that lives elsewhere, in QrOptions, because it changes the encoded symbol itself.
Dimensions sets the code size in pixels and Margins the quiet zone on all four sides, while MarginTop and the other sides set one side each. Color paints the dark modules and BackgroundColor the light area and margins. Logo takes a QrLogo with the bitmap, width, height and corner radius.
In our probe, a 400-pixel code with 50-pixel top and bottom margins and 20-pixel side margins saved at 440 x 500. The resize guide, the margins guide, and the colors guide show each setting on its own.
Please note: Calling Save with no argument on a code that has never been styled returns a 250 x 250 image. That size is an internal default.
How large can a logo be at each error correction level?
Smaller than the correction percentages suggest. Those figures count the codewords Reed-Solomon decoding can rebuild, and a central logo is only one source of damage. We rendered the spring-sale URL at 600 pixels with a plain square logo, let IronQR size it automatically, and then raised a manual size one percent at a time until IronQR refused to save it.
Level
Documented recovery
Automatic logo (width, area)
Largest manual logo (width, area)
Low
7%
20%, 4.0%
23%, 5.3%
Medium
15%
30%, 9.0%
31%, 9.6%
High
25%
32.5%, 10.6%
39%, 15.2%
Highest
30%
32%, 10.2%
44%, 19.4%
In the 2026.10.1 assembly, automatic sizing tries a short list of fractions of the code width, from one half down to one twentieth, and keeps the first one its reader decodes. That list explains why High and Highest land near one third of the width. A manual size goes higher, to between about 60 and 75 percent of the documented recovery by area, but IronQR checks it with its own reader at full resolution. A second scan mode can still fail where that check passed.
The figures depend on the payload. A longer URL produces a denser symbol with different limits, so treat the table as the shape of the trade-off and let the matrix measure your own campaigns.
How do you test every styled IronQR variant in one prompt?
Ask for the whole grid in one prompt and let plan mode settle the design first. Press Shift+Tab until the status bar shows plan mode, then send the prompt.
Build Services/BrandedQrRenderer.cs, which renders one campaign from@Brand/campaigns.json for a given QrErrorCorrectionLevel, logo mode, andpixel size, and Services/ScanMatrix.cs, which renders every campaign at everycorrection level (Low, Medium, High, Highest), with three logo modes (nologo, a QrLogo of width and height 0 so IronQR sizes it, and a manual logo 30percent of Dimensions wide that keeps the logo's aspect ratio), at the posterand sticker sizes in the JSON. Call the matrix from Program.cs after thespring-sale code. Save each PNG under out/matrix/. Decode every saved filetwice with a new QrReader each time, once with QrScanMode.Auto and once withQrScanMode.OnlyBasicScan, and catch exceptions per file, including any thatSave throws. Write out/scan-matrix.csv with campaign, level, logo mode, size,image width and height, the save result, and both read results, then printhow many variants decode to the exact URL in both modes. When the matrix hasrun, have the general-purpose subagent check every IronQR member in the newfiles against IronQr.xml and list any it cannot find.
Build Services/BrandedQrRenderer.cs, which renders one campaign from
@Brand/campaigns.json for a given QrErrorCorrectionLevel, logo mode, and
pixel size, and Services/ScanMatrix.cs, which renders every campaign at every
correction level (Low, Medium, High, Highest), with three logo modes (no
logo, a QrLogo of width and height 0 so IronQR sizes it, and a manual logo 30
percent of Dimensions wide that keeps the logo's aspect ratio), at the poster
and sticker sizes in the JSON. Call the matrix from Program.cs after the
spring-sale code. Save each PNG under out/matrix/. Decode every saved file
twice with a new QrReader each time, once with QrScanMode.Auto and once with
QrScanMode.OnlyBasicScan, and catch exceptions per file, including any that
Save throws. Write out/scan-matrix.csv with campaign, level, logo mode, size,
image width and height, the save result, and both read results, then print
how many variants decode to the exact URL in both modes. When the matrix has
run, have the general-purpose subagent check every IronQR member in the new
files against IronQr.xml and list any it cannot find.
Text
Each clause closes a way the results could look better than they are.
Every combination is named: three campaigns, four levels, three logo modes, and two sizes make 72 variants, so a missing row in out/scan-matrix.csv is visible.
Save failures are rows: a refused save is a result, and those rows show where the logo size limit sits.
A fresh reader for each read: one failing read cannot affect the next.
A second agent checks the API: the general-purpose subagent loads CLAUDE.md, which the built-in Explore and Plan subagents skip, so the check sees the project's rules.
Tips: Approve the plan only after it lists every variant and shows a try block around each one.
What should you verify before trusting generated IronQR code?
QrScanMode.Auto falls back to the basic scan only when its detection model finds nothing, and the enum's own documentation describes it as the detection model first, then "a basic brute-force read if none are found". When the model finds the code but cannot decode it, Auto returns an empty result and the basic scan never runs.
The basic scan decoded every Quickstart variant that failed above, and the exception comes from inside IronQR 2026.10.1. In our calibration run of the full matrix, every file Auto missed had a logo, and six of the eight were at High or Highest, the two levels with the most redundancy to spend on a logo. In the tested run, with a flat 10-pixel margin the agent chose, two of the eight Auto misses had no logo at all.
Add these checks to the same review.
The build: an invented member fails dotnet build, and so does a using directive spelled IronQR, which uses the package's casing while the namespace is IronQr.
The sizes: compare each saved width with the requested size plus both side margins. A mismatch shows a style that never reached the save call.
The payload: decode the file on disk. Verify compares text with IronQR's own in-memory rendering, so a file path returns false and a file written with the wrong style goes unnoticed.
We sent the three prompts above to Claude Code in order, in one session. The brand file held three campaigns, a 600-pixel poster size and a 120-pixel sticker size, beside a square logo and a wide wordmark. A separate Release build of a clean copy then reran the matrix and wrote an identical CSV, and an independent decode of every saved PNG agreed with each row.
On its first run the matrix matched 0 of 72 variants in both modes. After Claude Code removed the using block on QrImageInput, 55 of 72 matched.
IronQR refused 9 variants at save, every one with the manual logo. Of the 63 files it saved, the basic scan decoded all 63 and Auto decoded 55.
For the Quickstart, Claude Code chose a 300-pixel code with 10-pixel margins and a 50 x 50 logo. Its 320 x 320 PNG matched the URL on the first read.
The subagent found no IronQR member missing from IronQr.xml.
Every prompt left a clean Release build with no hand edits, and the matrix totals equal the calibration run.
A typed reply approved the third prompt's plan in place of the plan dialog, because the session ran non-interactively.
Versions, models, timings and the test machine for this guide and its siblings sit in the shared run record.
Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.