diff --git a/QRCoderTests/QRCoderTests.csproj b/QRCoderTests/QRCoderTests.csproj
index aec5434f..1b1c5d33 100644
--- a/QRCoderTests/QRCoderTests.csproj
+++ b/QRCoderTests/QRCoderTests.csproj
@@ -14,6 +14,7 @@
+
@@ -59,11 +60,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/QRCoderTests/TransposeVerificationTests.artqrcode_renderer.approved.gif b/QRCoderTests/TransposeVerificationTests.artqrcode_renderer.approved.gif
new file mode 100644
index 00000000..b8b51659
Binary files /dev/null and b/QRCoderTests/TransposeVerificationTests.artqrcode_renderer.approved.gif differ
diff --git a/QRCoderTests/TransposeVerificationTests.ascii_renderer.FullSize.approved.txt b/QRCoderTests/TransposeVerificationTests.ascii_renderer.FullSize.approved.txt
new file mode 100644
index 00000000..ec53d7cc
--- /dev/null
+++ b/QRCoderTests/TransposeVerificationTests.ascii_renderer.FullSize.approved.txt
@@ -0,0 +1,29 @@
+
+
+
+
+ ██████████████ ██ ████ ██████████████
+ ██ ██ ████ ██ ██ ██
+ ██ ██████ ██ ████ ██ ██ ██████ ██
+ ██ ██████ ██ ██ ██ ██ ██████ ██
+ ██ ██████ ██ ██ ██ ██ ██████ ██
+ ██ ██ ██ ████ ██ ██
+ ██████████████ ██ ██ ██ ██████████████
+ ██████████
+ ████ ██ ████ ████ ██████ ████
+ ██ ████████ ████ ██
+ ██ ██ ██ ██████ ████ ██
+ ██ ██████ ████ ██ ██ ████
+ ██████ ██ ██████████ ██ ██ ████████
+ ████ ██ ██████ ██
+ ██████████████ ████ ██ ██ ██
+ ██ ██ ██████████ ██████ ████
+ ██ ██████ ██ ██ ██ ██████ ██████
+ ██ ██████ ██ ████ ██ ████████
+ ██ ██████ ██ ██ ██ ██ ██
+ ██ ██ ████ ████ ██ ██ ██
+ ██████████████ ██ ██████ ██████
+
+
+
+
\ No newline at end of file
diff --git a/QRCoderTests/TransposeVerificationTests.ascii_renderer.Small.approved.txt b/QRCoderTests/TransposeVerificationTests.ascii_renderer.Small.approved.txt
new file mode 100644
index 00000000..fd8ff2b3
--- /dev/null
+++ b/QRCoderTests/TransposeVerificationTests.ascii_renderer.Small.approved.txt
@@ -0,0 +1,15 @@
+
+
+ █▀▀▀▀▀█ ▄█ █▀ █▀▀▀▀▀█
+ █ ███ █ ▀█ ▄▀ █ ███ █
+ █ ▀▀▀ █ █ ▄█ █ ▀▀▀ █
+ ▀▀▀▀▀▀▀ █▄█▄█ ▀▀▀▀▀▀▀
+ █▀▄█▄▄▀▀▄█▀ █▀▀ ▀▀
+ ▀▄ █▄▄▀ ██▀▄▀▀ ▄▀▄▄
+ ▀▀▀ ▀ ▀▀██▀▄▀ ▀▄██▀█
+ █▀▀▀▀▀█ ▀█▄▄▄█ █▄█ ▄▄
+ █ ███ █ ▄█ █ ▀▀▀▄███
+ █ ▀▀▀ █ ▄█ ▀▄▄ █ ▄ █
+ ▀▀▀▀▀▀▀ ▀ ▀▀▀ ▀▀▀
+
+
\ No newline at end of file
diff --git a/QRCoderTests/TransposeVerificationTests.black_module_reference.approved.gif b/QRCoderTests/TransposeVerificationTests.black_module_reference.approved.gif
new file mode 100644
index 00000000..60f763b7
Binary files /dev/null and b/QRCoderTests/TransposeVerificationTests.black_module_reference.approved.gif differ
diff --git a/QRCoderTests/TransposeVerificationTests.cs b/QRCoderTests/TransposeVerificationTests.cs
new file mode 100644
index 00000000..fd8e0d4f
--- /dev/null
+++ b/QRCoderTests/TransposeVerificationTests.cs
@@ -0,0 +1,171 @@
+using System.IO;
+
+namespace QRCoderTests;
+
+///
+/// Tests to verify that QR codes are not transposed along the main diagonal.
+/// All tests use the same QR code data with default renderer settings.
+/// Human verification of approval files is required to ensure correct orientation.
+///
+public class TransposeVerificationTests
+{
+ private readonly QRCodeData _sharedQrCodeData;
+
+ public TransposeVerificationTests()
+ {
+ // Create a single QR code sample that will be used across all tests
+ // Using a distinctive pattern that makes transpose errors obvious
+ var gen = new QRCodeGenerator();
+ _sharedQrCodeData = gen.CreateQrCode("ABCD", QRCodeGenerator.ECCLevel.L);
+ }
+
+#if SYSTEM_DRAWING
+ [Theory]
+ [InlineData("QRCode")]
+ [InlineData("BitmapByteQRCode")]
+ [InlineData("Base64QRCode")]
+ [InlineData("PngByteQRCode")]
+ [InlineData("SvgQRCode")]
+ public void image_renderers(string rendererType)
+ {
+ byte[] imageBytes = rendererType switch
+ {
+ "QRCode" => GetQRCodeBytes(),
+ "BitmapByteQRCode" => GetBitmapByteQRCodeBytes(),
+ "Base64QRCode" => GetBase64QRCodeBytes(),
+ "PngByteQRCode" => GetPngByteQRCodeBytes(),
+ "SvgQRCode" => GetSvgQRCodeBytes(),
+ _ => throw new ArgumentException($"Unknown renderer type: {rendererType}")
+ };
+
+ imageBytes.ShouldMatchApprovedImage(asMonochrome: true);
+ }
+
+ private byte[] GetQRCodeBytes()
+ {
+ var qrCode = new QRCode(_sharedQrCodeData);
+ using var bitmap = qrCode.GetGraphic(10);
+ using var ms = new MemoryStream();
+ bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
+ return ms.ToArray();
+ }
+
+ private byte[] GetBitmapByteQRCodeBytes()
+ {
+ var qrCode = new BitmapByteQRCode(_sharedQrCodeData);
+ return qrCode.GetGraphic(10);
+ }
+
+ private byte[] GetBase64QRCodeBytes()
+ {
+ var qrCode = new Base64QRCode(_sharedQrCodeData);
+ var base64String = qrCode.GetGraphic(10);
+ return Convert.FromBase64String(base64String);
+ }
+
+ private byte[] GetPngByteQRCodeBytes()
+ {
+ var qrCode = new PngByteQRCode(_sharedQrCodeData);
+ return qrCode.GetGraphic(10);
+ }
+
+ private byte[] GetSvgQRCodeBytes()
+ {
+ var qrCode = new SvgQRCode(_sharedQrCodeData);
+ var svgString = qrCode.GetGraphic(10);
+ var bitmapSize = _sharedQrCodeData.ModuleMatrix.Count * 10;
+ // use Svg.Net to render SVG to bitmap for comparison
+ var svgDoc = Svg.SvgDocument.FromSvg(svgString);
+ using var bitmap = svgDoc.Draw(bitmapSize, bitmapSize);
+ using var ms = new MemoryStream();
+ bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
+ return ms.ToArray();
+ }
+
+ [Fact]
+ public void artqrcode_renderer()
+ {
+ var qrCode = new ArtQRCode(_sharedQrCodeData);
+ using var bitmap = qrCode.GetGraphic(10, Color.Black, Color.White, Color.White, null, 1, true, ArtQRCode.QuietZoneStyle.Flat, ArtQRCode.BackgroundImageStyle.Fill, null);
+ bitmap.ShouldMatchApproved();
+ }
+#endif
+
+ [Theory]
+ [InlineData("FullSize")]
+ [InlineData("Small")]
+ public void ascii_renderer(string sizeType)
+ {
+ var qrCode = new AsciiQRCode(_sharedQrCodeData);
+ var asciiArt = sizeType switch
+ {
+ "FullSize" => qrCode.GetGraphic(1),
+ "Small" => qrCode.GetGraphicSmall(invert: true),
+ _ => throw new ArgumentException($"Unknown size type: {sizeType}")
+ };
+ asciiArt.ShouldMatchApproved(x => x.NoDiff().WithDiscriminator(sizeType));
+ }
+
+ [Fact]
+ public void pdf_renderer()
+ {
+ var qrCode = new PdfByteQRCode(_sharedQrCodeData);
+ var pdfBytes = qrCode.GetGraphic(10);
+ pdfBytes.ShouldMatchApproved("pdf");
+ }
+
+ [Fact]
+ public void postscript_renderer()
+ {
+ var qrCode = new PostscriptQRCode(_sharedQrCodeData);
+ var postscript = qrCode.GetGraphic(10);
+ postscript.ShouldMatchApproved(x => x.NoDiff().WithFileExtension("ps"));
+ }
+
+ [Fact]
+ public void black_module_position()
+ {
+ // The black module in a QR code is always at position (4*version + 9, 8) + (4,4) due to the quiet zone
+ // For our test QR code (version 1), it should be at (13, 8)
+ // If transposed, it would be at (8, 13)
+ var version = _sharedQrCodeData.Version;
+ var expectedRow = 4 * version + 9 + 4;
+ var expectedCol = 8 + 4;
+ var transposedRow = expectedCol;
+ var transposedCol = expectedRow;
+
+ // Verify the black module is at the expected position
+ _sharedQrCodeData.ModuleMatrix[expectedRow][expectedCol].ShouldBeTrue(
+ $"Black module should be at position ({expectedRow}, {expectedCol})");
+
+ // Verify it's NOT at the transposed position (unless they happen to be the same)
+ if (expectedRow != transposedCol || expectedCol != transposedRow)
+ {
+ _sharedQrCodeData.ModuleMatrix[transposedRow][transposedCol].ShouldBeFalse(
+ $"Black module should NOT be at transposed position ({transposedRow}, {transposedCol})");
+ }
+ }
+
+#if SYSTEM_DRAWING
+ [Fact]
+ public void black_module_reference()
+ {
+ // Create a QR code data with the same size as our test matrix
+ // but with only a single black module at the expected black module position
+ var version = _sharedQrCodeData.Version;
+ var blackModuleRow = 4 * version + 9 + 4;
+ var blackModuleCol = 8 + 4;
+
+ // Create a minimal QRCodeData with just the black module
+ var referenceData = new QRCodeData(version, addPadding: true);
+
+ // Set only the black module position to true
+ referenceData.ModuleMatrix[blackModuleRow][blackModuleCol] = true;
+
+ // Render this reference image for human verification
+ var qrCode = new QRCode(referenceData);
+ using var bitmap = qrCode.GetGraphic(10);
+ bitmap.ShouldMatchApproved();
+ }
+#endif
+}
diff --git a/QRCoderTests/TransposeVerificationTests.image_renderers.approved.gif b/QRCoderTests/TransposeVerificationTests.image_renderers.approved.gif
new file mode 100644
index 00000000..5db6923e
Binary files /dev/null and b/QRCoderTests/TransposeVerificationTests.image_renderers.approved.gif differ
diff --git a/QRCoderTests/TransposeVerificationTests.pdf_renderer.approved.pdf b/QRCoderTests/TransposeVerificationTests.pdf_renderer.approved.pdf
new file mode 100644
index 00000000..51acbf02
Binary files /dev/null and b/QRCoderTests/TransposeVerificationTests.pdf_renderer.approved.pdf differ
diff --git a/QRCoderTests/TransposeVerificationTests.postscript_renderer.approved.ps b/QRCoderTests/TransposeVerificationTests.postscript_renderer.approved.ps
new file mode 100644
index 00000000..0aef3dfa
Binary files /dev/null and b/QRCoderTests/TransposeVerificationTests.postscript_renderer.approved.ps differ