Open peterkorolev opened 7 years ago
@peterkorolev It's possible, but must find a pattern version of QR Code is smaller than this.
He probably means "lower ECC". I have the same issue, the generated QR has a lot of redundancy and uses very small pixes (one pixel QR = 1 pixel OLED). I'd need lower ECC version which might generate QRs with 1 Pixel QR = 4 Pixel OLED: The original Arduino qrence library does offer generation between ECC 1 and 4. I need to look that up.
this lib works pretty fine for me: https://github.com/nayuki/QR-Code-generator/tree/master/c
allows to autopick the lowest possible version and auto adjusts ECC
put the qrcodegen.c / qrcodegen.h files from the project above in the same directory as the following 2 files and it should work (only tested on esp32 with esp-idf and arduino-esp32 lib)
qrencode.h
#include "OLEDDisplay.h"
#include "qrcodegen.h"
// https://www.qrcode.com/en/about/version.html QR version overview
#define QRENCODE_VERSION_MIN (1)
#define QRENCODE_VERSION_MAX (7) // should work up to 11 (61 x 61)
class QREncode
{
private:
String QRBuffer = "";
uint8_t code[qrcodegen_BUFFER_LEN_FOR_VERSION(QRENCODE_VERSION_MAX)];
int resolution = 0;
char maxScale = 0;
void create(OLEDDisplay *display, String message);
void render(OLEDDisplay *display, int x, int y);
public:
void render(OLEDDisplay *display, String message, int x, int y){
create(display, message);
render(display, x, y);
}
};
qrencode.cpp
#include "qrencode.h"
void QREncode::create(OLEDDisplay *display, String message) {
// dont reencode code if nothing changed
if(message.equals(QRBuffer))
return;
QRBuffer = message;
uint8_t buffer[qrcodegen_BUFFER_LEN_FOR_VERSION(QRENCODE_VERSION_MAX)];
resolution = 0;
maxScale = 1;
if(qrcodegen_encodeText(message.c_str(), &buffer[0], &code[0], qrcodegen_Ecc_LOW, QRENCODE_VERSION_MIN, QRENCODE_VERSION_MAX, qrcodegen_Mask_AUTO, true)){
resolution = qrcodegen_getSize(code);
while((maxScale + 1) * resolution < display->height())
maxScale++;
printf("QR created, size: %d, scale factor: %d", resolution, maxScale);
}
else {
printf((char *) "failed to create QR code");
}
}
void QREncode::render(OLEDDisplay *display, int x, int y) {
int renderResolution = resolution * maxScale;
int offsetX = x + (display->height() - renderResolution) / 2;
int offsetY = y + (display->height() - renderResolution) / 2;
display->fillRect(offsetX - 2, offsetY - 2, renderResolution + 4, renderResolution + 4);
// draw QR Code
for (char x = 0; x < renderResolution; x++) {
for (char y = 0; y < renderResolution; y++) {
display->setPixelColor(offsetX + x, offsetY + y, qrcodegen_getModule(code, x / maxScale, y / maxScale) ? BLACK : WHITE);
}
}
}
@ben-mkiv Pretty good answer, but a few corrections:
qrcodegen_encodeSegmentsAdvanced()
; otherwise you might smash an array.Thanks @nayuki, i've edited my post according to your suggestions.
I've included the c file because it didn't compile for me with just the header (using CLion with ESP-IDF, so i probably just have to make it it's own component or fiddle with the CMake config)
Hi!
Is it possible to use a lower version of QR code? With lower resolution/memory