PixelRenderer: now respecting the specified output size exactly

output is now padded by the border to prevent changing the output size
specified by the user. this may result in the QR code not being exactly
in the center. it may be off by 1 pixel.
pull/1/head
Michael Ochmann 2 years ago
parent cfc0d276dc
commit 6f3827427b
  1. 5
      main.cpp
  2. 9
      src/renderers/PixelRenderer.hpp

@ -20,8 +20,9 @@ Usage: qr [OPTION]... --input "data to encapsulate"
*Caveats* *Caveats*
With no `--input` parameter defined, read STDIN With no `--input` parameter defined, read STDIN
In pixel based renderers (i.e. PNG), the output size may not be exactly as In pixel based renderers (i.e. PNG), the output code may not be exactly
specified but be the nearest multiple of the actual cell size for the QR code. centered, as the amount of segment may not correspond to the specified
output size.
Options: Options:
-f --format output file format. can be one of "cli, png, svg, jpg, bmp" -f --format output file format. can be one of "cli, png, svg, jpg, bmp"

@ -13,6 +13,7 @@ namespace massivedynamic {
class PixelRenderer : public Renderer { class PixelRenderer : public Renderer {
protected: protected:
size_t pixelSize; size_t pixelSize;
size_t border;
std::vector<Color> bitmap; std::vector<Color> bitmap;
void drawPixelScaled(size_t x, size_t y, Color color) { void drawPixelScaled(size_t x, size_t y, Color color) {
@ -23,8 +24,8 @@ namespace massivedynamic {
exit(1); exit(1);
} }
size_t absoluteX = pixelSize * x + pixelSize; size_t absoluteX = pixelSize * x + this->border;
size_t absoluteY = pixelSize * y + pixelSize; size_t absoluteY = pixelSize * y + this->border;
for (size_t localY = absoluteY; localY < absoluteY + pixelSize; localY++) { for (size_t localY = absoluteY; localY < absoluteY + pixelSize; localY++) {
for (size_t localX = absoluteX; localX < absoluteX + pixelSize; localX++) { for (size_t localX = absoluteX; localX < absoluteX + pixelSize; localX++) {
@ -40,10 +41,8 @@ namespace massivedynamic {
PixelRenderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : Renderer(pixels, sourceSize, targetSize), pixelSize(0) { PixelRenderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : Renderer(pixels, sourceSize, targetSize), pixelSize(0) {
this->targetSize = this->targetSize == 0 ? (sourceSize + 2) * 2 : this->targetSize; this->targetSize = this->targetSize == 0 ? (sourceSize + 2) * 2 : this->targetSize;
// here we make shure, `targetSize` will be a multiple of `sourceSize`
this->pixelSize = round(static_cast<float>(this->targetSize) / static_cast<float>(this->sourceSize + 2)); this->pixelSize = round(static_cast<float>(this->targetSize) / static_cast<float>(this->sourceSize + 2));
this->targetSize = (this->sourceSize + 2) * this->pixelSize; this->border = round((this->targetSize - this->pixelSize * this->sourceSize) / 2);
this->bitmap = std::vector<Color>(this->targetSize * this->targetSize, Colors::WHITE); this->bitmap = std::vector<Color>(this->targetSize * this->targetSize, Colors::WHITE);
} }

Loading…
Cancel
Save