Skip to content

Commit 91839cf

Browse files
committed
Rename and make pixels crop to module pixels size
1 parent 102d3e0 commit 91839cf

File tree

1 file changed

+77
-29
lines changed

1 file changed

+77
-29
lines changed

QRCoder/LogoQRCode.cs renamed to QRCoder/ArtQRCode.cs

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,33 @@
77
// pull request raised to extend library used.
88
namespace QRCoder
99
{
10-
public class LogoQRCode : AbstractQRCode, IDisposable
10+
public class ArtQRCode : AbstractQRCode, IDisposable
1111
{
1212
/// <summary>
1313
/// Constructor without params to be used in COM Objects connections
1414
/// </summary>
15-
public LogoQRCode() { }
15+
public ArtQRCode() { }
1616

17-
public LogoQRCode(QRCodeData data) : base(data) { }
17+
public ArtQRCode(QRCodeData data) : base(data) { }
1818

19-
public Bitmap GetGraphic(Bitmap backgroundImage = null)
19+
public Bitmap GetGraphic(int pixelsPerModule)
2020
{
21-
return this.GetGraphic(10, 7, Color.Black, Color.White, backgroundImage: backgroundImage);
21+
return this.GetGraphic(pixelsPerModule, (pixelsPerModule * 8) / 10, Color.Black, Color.White);
2222
}
2323

24-
public Bitmap GetGraphic(int pixelsPerModule, Bitmap backgroundImage = null)
24+
public Bitmap GetGraphic(Bitmap backgroundImage = null)
2525
{
26-
return this.GetGraphic(pixelsPerModule, (pixelsPerModule * 8) / 10, Color.Black, Color.White, backgroundImage: backgroundImage);
26+
return this.GetGraphic(10, 7, Color.Black, Color.White, backgroundImage: backgroundImage);
2727
}
2828

29-
public Bitmap GetGraphic(int pixelsPerModule,
29+
public Bitmap GetGraphic(
30+
int pixelsPerModule,
3031
int pixelSize,
3132
Color darkColor,
3233
Color lightColor,
33-
Bitmap backgroundImage = null,
3434
bool drawQuietZones = false,
35-
Bitmap reticleImage = null)
35+
Bitmap reticleImage = null,
36+
Bitmap backgroundImage = null)
3637
{
3738
int numModules = this.QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8);
3839
var offset = (drawQuietZones ? 0 : 4);
@@ -42,6 +43,7 @@ public Bitmap GetGraphic(int pixelsPerModule,
4243
Bitmap bitmap = backgroundImage ?? new Bitmap(size, size);
4344
bitmap = Resize(bitmap, size);
4445

46+
4547
using (Graphics graphics = Graphics.FromImage(bitmap))
4648
{
4749
using (SolidBrush lightBrush = new SolidBrush(lightColor))
@@ -57,21 +59,23 @@ public Bitmap GetGraphic(int pixelsPerModule,
5759
}
5860
}
5961

62+
var darkModulePixel = MakeDotPixel(pixelsPerModule, pixelSize, darkBrush);
63+
var lightModulePixel = MakeDotPixel(pixelsPerModule, pixelSize, lightBrush);
64+
6065
for (int x = 0; x < numModules; x += 1)
6166
{
6267
for (int y = 0; y < numModules; y += 1)
6368
{
64-
var solidBrush = (Brush)(this.QrCodeData.ModuleMatrix[offset + y][offset + x] ? darkBrush : lightBrush);
65-
66-
if (IsPartOfReticle(x, y, numModules, offset))
67-
{
68-
if (reticleImage == null)
69-
{
70-
graphics.FillRectangle(solidBrush, new Rectangle(x * pixelsPerModule, y * pixelsPerModule, pixelsPerModule, pixelsPerModule));
71-
}
72-
}
73-
else
74-
graphics.FillEllipse(solidBrush, new Rectangle(x * pixelsPerModule + moduleMargin, y * pixelsPerModule + moduleMargin, pixelSize, pixelSize));
69+
var rectangleF = new Rectangle(x * pixelsPerModule, y * pixelsPerModule, pixelsPerModule, pixelsPerModule);
70+
71+
var pixelIsDark = this.QrCodeData.ModuleMatrix[offset + y][offset + x];
72+
var solidBrush = pixelIsDark ? darkBrush : lightBrush;
73+
var pixelImage = pixelIsDark ? darkModulePixel : lightModulePixel;
74+
75+
if (!IsPartOfReticle(x, y, numModules, offset))
76+
graphics.DrawImage(pixelImage, rectangleF);
77+
else if (reticleImage == null)
78+
graphics.FillRectangle(solidBrush, rectangleF);
7579
}
7680
}
7781

@@ -90,6 +94,39 @@ public Bitmap GetGraphic(int pixelsPerModule,
9094
return bitmap;
9195
}
9296

97+
/// <summary>
98+
/// If the pixelSize is bigger than the pixelsPerModule or may end up filling the Module making a traditional QR code.
99+
/// </summary>
100+
/// <param name="pixelsPerModule"></param>
101+
/// <param name="pixelSize"></param>
102+
/// <param name="brush"></param>
103+
/// <returns></returns>
104+
private Bitmap MakeDotPixel(int pixelsPerModule, int pixelSize, SolidBrush brush)
105+
{
106+
// draw a dot
107+
var bitmap = new Bitmap(pixelSize, pixelSize);
108+
using (var graphics = Graphics.FromImage(bitmap))
109+
{
110+
graphics.FillEllipse(brush, new Rectangle(0, 0, pixelSize, pixelSize));
111+
graphics.Save();
112+
}
113+
114+
var pixelWidth = Math.Min(pixelsPerModule, pixelSize);
115+
var margin = Math.Max((pixelsPerModule - pixelWidth) / 2, 0);
116+
117+
// center the dot in the module and crop to stay the right size.
118+
var cropped = new Bitmap(pixelsPerModule, pixelsPerModule);
119+
using (var graphics = Graphics.FromImage(cropped))
120+
{
121+
graphics.DrawImage(bitmap, new Rectangle(margin, margin, pixelWidth, pixelWidth),
122+
new RectangleF(((float)pixelSize - pixelWidth) / 2, ((float)pixelSize - pixelWidth) / 2, pixelWidth, pixelWidth),
123+
GraphicsUnit.Pixel);
124+
graphics.Save();
125+
}
126+
127+
return cropped;
128+
}
129+
93130
private bool IsPartOfReticle(int x, int y, int numModules, int offset)
94131
{
95132
var cornerSize = 11 - offset;
@@ -99,25 +136,36 @@ private bool IsPartOfReticle(int x, int y, int numModules, int offset)
99136
(x < cornerSize && y > (numModules - cornerSize - 1));
100137
}
101138

102-
private Bitmap Resize(Bitmap image, int size)
139+
/// <summary>
140+
/// Resize to a square bitmap, but maintain the aspect ratio by padding transparently.
141+
/// </summary>
142+
///
143+
/// <param name="image"></param>
144+
/// <param name="newSize"></param>
145+
/// <returns></returns>
146+
private Bitmap Resize(Bitmap image, int newSize)
103147
{
104-
float scale = Math.Min((float)size / image.Width, (float)size / image.Height);
105-
var scaleWidth = (int)(image.Width * scale);
106-
var scaleHeight = (int)(image.Height * scale);
107-
var scaledImage = new Bitmap(image, new Size(scaleWidth, scaleHeight));
148+
float scale = Math.Min((float)newSize / image.Width, (float)newSize / image.Height);
149+
var scaledWidth = (int)(image.Width * scale);
150+
var scaledHeight = (int)(image.Height * scale);
151+
var offsetX = (newSize - scaledWidth) / 2;
152+
var offsetY = (newSize - scaledHeight) / 2;
153+
154+
var scaledImage = new Bitmap(image, new Size(scaledWidth, scaledHeight));
108155

109-
var bm = new Bitmap(size, size);
156+
var bm = new Bitmap(newSize, newSize);
110157

111158
using (Graphics graphics = Graphics.FromImage(bm))
112159
{
113160
using (var brush = new SolidBrush(Color.Transparent))
114161
{
115-
graphics.FillRectangle(brush, new Rectangle(0, 0, size, size));
162+
graphics.FillRectangle(brush, new Rectangle(0, 0, newSize, newSize));
116163

117164
graphics.InterpolationMode = InterpolationMode.High;
118165
graphics.CompositingQuality = CompositingQuality.HighQuality;
119166
graphics.SmoothingMode = SmoothingMode.AntiAlias;
120-
graphics.DrawImage(scaledImage, new Rectangle((size / 2) - (scaledImage.Width / 2), (size / 2) - (scaledImage.Height / 2), scaledImage.Width, scaledImage.Height));
167+
168+
graphics.DrawImage(scaledImage, new Rectangle(offsetX, offsetY, scaledWidth, scaledHeight));
121169
}
122170
}
123171

0 commit comments

Comments
 (0)