user43459: So I have a project where I send text to an Arduino, which is then printed out as a QR code on a thermal printer that can take a bitmap image with a given width and height.
Is there a way I can "scale up" the "image," making it so one pixel is scaled up to 4 or 8 pixels?
Additionally, would it be possible to add a "quiet zone" of sorts on the left side of the image, as I am not able to offset/justify it to the middle.
QR Code lib: https://github.com/ricmoo/QRCode
Thermal printer lib: https://github.com/adafruit/Adafruit-Thermal-Printer-Library

user7508: You didn't tell use the size of your QRCode, nor the type of Arduino you
are using. So I am just going to guess that your problem is that you may
have enough RAM to store the raw QRCode, but not enough to store a
scaled bitmap version.
The Adafruit tutorial for their thermal printer library suggests
printing bitmaps with the method:
printBitmap(width, height, tablename)

where tablename is an array holding the bitmap data. This will
obviously not work if you don't have enough RAM to store the array.
Fortunately, there is an overloaded method:
void Adafruit_Thermal::printBitmap(int w, int h, Stream *fromStream)

that allows you to stream the image data instead of preparing it in RAM.
You can create a stream that delivers arbitrary data by writing a class
that derives from Stream. Here is a tentative, untested
implementation, that delivers a scaled-up QRCode one pixel at a time:
// Stream a scaled QRCode one pixel at a time.
class QRCodeStream : public Stream
{
public:
    QRCodeStream(const QRCode &code, uint8_t scale = 1)
    : qrcode(code), scale(scale) {}

    // Output: writing to this stream is a no-op.
    size_t write(uint8_t) {}
    void flush() {}

    // Input delivers the QRCode pixels.
    int available();
    int peek();
    int read();
private:
    QRCode &qrcode;
    uint8_t scale;
    bool done = false;
    uint8_t code_x = 0;  // coordinates of the QRCode module
    uint8_t code_y = 0;
    uint8_t pix_x = 0;  // pixel coordinates within the module
    uint8_t pix_y = 0;
};

int QRCodeStream::available()
{
    // For simplicity, pretend the bytes come one at a time.
    if (done) return 0;
    else return 1;
}

int QRCodeStream::peek()
{
    if (done) return -1;
    if (qrcode_getModule(&qrcode, code_x, code_y)) {
        return 0;  // black
    } else {
        return 255;  // white
    }
}

int QRCodeStream::read()
{
    if (done) return -1;
    int data = peek();

    // Move to the next pixel.
    if (++pix_x >= scale) {
        pix_x = 0;
        if (++code_x >= qrcode.size) {
            code_x = 0;
            if (++pix_y >= scale) {
                pix_y = 0;
                if (++code_y >= qrcode.size) {
                    done = true;
                }
            }
        }
    }

    return data;
}

This would be used as
printer.printBitmap(width, height, QRCodeStream(qrcode, scale));

Note that QRCodeStream delivers the image data as 8-bit gray scale,
where each pixel is returned as one byte, either 0 (for black) or 255
(for white). This is likely not the format expected by the thermal
printer library, which seems to expect 1-bit black and white data, with
8 pixels packed in each byte. You will have to adapt the code for
the right format, which will likely be tedious, but not overly complex.
I leave that “as an exercise to the reader”.

43459: <p>So I have a project where I send text to an Arduino, which is then printed out as a QR code on a thermal printer that can take a bitmap image with a given width and height.</p>

<p>Is there a way I can "scale up" the "image," making it so one pixel is scaled up to 4 or 8 pixels?</p>

<p>Additionally, would it be possible to add a "quiet zone" of sorts on the left side of the image, as I am not able to offset/justify it to the middle.</p>

<p>QR Code lib: <a href="https://github.com/ricmoo/QRCode" rel="nofollow noreferrer">https://github.com/ricmoo/QRCode</a></p>

<p>Thermal printer lib: <a href="https://github.com/adafruit/Adafruit-Thermal-Printer-Library" rel="nofollow noreferrer">https://github.com/adafruit/Adafruit-Thermal-Printer-Library</a></p>
 7508: <p>You didn't tell use the size of your QRCode, nor the type of Arduino you
are using. So I am just going to guess that your problem is that you may
have enough RAM to store the raw QRCode, but not enough to store a
scaled bitmap version.</p>

<p>The <a href="https://learn.adafruit.com/mini-thermal-receipt-printer?view=all#bitmap-printing" rel="nofollow noreferrer">Adafruit tutorial</a> for their thermal printer library suggests
printing bitmaps with the method:</p>

<pre class="lang-cpp prettyprint-override"><code>printBitmap(width, height, tablename)
</code></pre>

<p>where <code>tablename</code> is an array holding the bitmap data. This will
obviously not work if you don't have enough RAM to store the array.
Fortunately, there is an overloaded method:</p>

<pre class="lang-cpp prettyprint-override"><code>void Adafruit_Thermal::printBitmap(int w, int h, Stream *fromStream)
</code></pre>

<p>that allows you to stream the image data instead of preparing it in RAM.
You can create a stream that delivers arbitrary data by writing a class
that derives from <code>Stream</code>. Here is a tentative, untested
implementation, that delivers a scaled-up QRCode one pixel at a time:</p>

<pre class="lang-cpp prettyprint-override"><code>// Stream a scaled QRCode one pixel at a time.
class QRCodeStream : public Stream
{
public:
    QRCodeStream(const QRCode &amp;code, uint8_t scale = 1)
    : qrcode(code), scale(scale) {}

    // Output: writing to this stream is a no-op.
    size_t write(uint8_t) {}
    void flush() {}

    // Input delivers the QRCode pixels.
    int available();
    int peek();
    int read();
private:
    QRCode &amp;qrcode;
    uint8_t scale;
    bool done = false;
    uint8_t code_x = 0;  // coordinates of the QRCode module
    uint8_t code_y = 0;
    uint8_t pix_x = 0;  // pixel coordinates within the module
    uint8_t pix_y = 0;
};

int QRCodeStream::available()
{
    // For simplicity, pretend the bytes come one at a time.
    if (done) return 0;
    else return 1;
}

int QRCodeStream::peek()
{
    if (done) return -1;
    if (qrcode_getModule(&amp;qrcode, code_x, code_y)) {
        return 0;  // black
    } else {
        return 255;  // white
    }
}

int QRCodeStream::read()
{
    if (done) return -1;
    int data = peek();

    // Move to the next pixel.
    if (++pix_x &gt;= scale) {
        pix_x = 0;
        if (++code_x &gt;= qrcode.size) {
            code_x = 0;
            if (++pix_y &gt;= scale) {
                pix_y = 0;
                if (++code_y &gt;= qrcode.size) {
                    done = true;
                }
            }
        }
    }

    return data;
}
</code></pre>

<p>This would be used as</p>

<pre class="lang-cpp prettyprint-override"><code>printer.printBitmap(width, height, QRCodeStream(qrcode, scale));
</code></pre>

<p>Note that <code>QRCodeStream</code> delivers the image data as 8-bit gray scale,
where each pixel is returned as one byte, either 0 (for black) or 255
(for white). This is likely not the format expected by the thermal
printer library, which seems to expect 1-bit black and white data, with
8&nbsp;pixels packed in each byte. You will have to adapt the code for
the right format, which will likely be tedious, but not overly complex.
I leave that “as an exercise to the reader”.</p>
