Как масштабировать растровое изображение (массив uint8_t) в Arduino?
Итак, у меня есть проект, в котором я отправляю текст на Arduino, который затем распечатывается в виде QR-кода на термопринтере, который может печатать растровое изображение заданной ширины и высоты.
Есть ли способ "увеличить" "изображение", сделав его таким, чтобы один пиксель увеличивался до 4 или 8 пикселей?
Кроме того, можно ли добавить своего рода "тихую зону" в левой части изображения, поскольку я не могу сместить/выровнять ее по центру.
Библиотека QR-кода: https://github.com/ricmoo/QRCode
Библиотека термопринтера: https://github.com/adafruit/Adafruit-Thermal-Printer-Library
@Tony Sesek, 👍2
Обсуждение1 ответ
Вы не указали ни размер вашего QRCode, ни тип Arduino. используют. Так что я просто собираюсь предположить, что ваша проблема в том, что вы можете иметь достаточно оперативной памяти для хранения необработанного QRCode, но недостаточно для хранения масштабированная растровая версия.
В руководстве Adafruit для библиотеки термопринтеров предлагается печать растровых изображений методом:
printBitmap(width, height, tablename)
где tablename
— это массив, содержащий растровые данные. Это будет
очевидно, не работает, если у вас недостаточно оперативной памяти для хранения массива.
К счастью, есть перегруженный метод:
void Adafruit_Thermal::printBitmap(int w, int h, Stream *fromStream)
что позволяет передавать данные изображения в потоковом режиме, а не подготавливать их в ОЗУ.
Вы можете создать поток, который доставляет произвольные данные, написав класс
который является производным от Stream
. Вот предварительный, непроверенный
реализация, которая предоставляет увеличенный QRCode по одному пикселю за раз:
// Потоковая передача масштабированного QRCode по одному пикселю за раз.
class QRCodeStream : public Stream
{
public:
QRCodeStream(const QRCode &code, uint8_t scale = 1)
: qrcode(code), scale(scale) {}
// Вывод: запись в этот поток не выполняется.
size_t write(uint8_t) {}
void flush() {}
// На вход поступают пиксели QRCode.
int available();
int peek();
int read();
private:
QRCode &qrcode;
uint8_t scale;
bool done = false;
uint8_t code_x = 0; // координаты модуля QRCode
uint8_t code_y = 0;
uint8_t pix_x = 0; // координаты пикселя внутри модуля
uint8_t pix_y = 0;
};
int QRCodeStream::available()
{
// Для простоты представьте, что байты приходят по одному.
if (done) return 0;
else return 1;
}
int QRCodeStream::peek()
{
if (done) return -1;
if (qrcode_getModule(&qrcode, code_x, code_y)) {
return 0; // черный
} else {
return 255; // белый
}
}
int QRCodeStream::read()
{
if (done) return -1;
int data = peek();
// Переход к следующему пикселю.
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;
}
Это будет использоваться как
printer.printBitmap(width, height, QRCodeStream(qrcode, scale));
Обратите внимание, что QRCodeStream
передает данные изображения в виде 8-битной шкалы серого,
где каждый пиксель возвращается как один байт, либо 0 (для черного), либо 255
(для белого). Скорее всего, это не тот формат, которого ожидает тепловизор.
библиотека принтера, которая, кажется, ожидает 1-битные черно-белые данные, с
В каждом байте упаковано 8 пикселей. Вам придется адаптировать код для
правильный формат, который, вероятно, будет утомительным, но не слишком сложным.
Я оставляю это «в качестве упражнения для читателя».
Извинения. Я использую ESP32, и Arduino IDE сообщает о максимальной памяти 327680 байт. И я стремлюсь получить как минимум QR-код версии 3 :), @Tony Sesek
А вот результаты шкал 1-3: https://i.imgur.com/7gBl0c1.jpg - Не уверен, что это из-за формата самого кода, или что-то еще..., @Tony Sesek
@TonySesek: Похоже, это работает, но каждый пиксель преобразуется в строку из 8 пикселей из-за разницы в формате 1 бит и 8 бит., @Edgar Bonet
Ох, мой мозг пропустил важную часть вашего постскриптума, мой плохой. Хорошо, это *не должно* быть слишком плохо. Может быть, я могу сделать еще один поток, чтобы взять поток, ха-ха., @Tony Sesek
- Ошибка: invalid application of 'sizeof' to incomplete type 'int []' при попытке вычислить размер массива в библиотеке
- Как определить, было ли нажато более одной кнопки
- Как я могу присвоить значение массива символов массиву uint8_t?
- Не удается успешно реализовать синглтон
- Самый прямой способ назначить байты Serial.read() массиву?
- Матрица и пространство состояний Реализация Arduino
- Разбор массива объекта в конструкторе библиотеки
- Создание массива с длиной, полученной из библиотеки
Попытка склейки в библиотеке QRPrint приводит к сбою ESP32 снова и снова., @Tony Sesek
Какой Ардуино? Большинству из них не хватило бы оперативной памяти для этого., @Nick Gammon
@NickGammon Я использую ESP32 с ядром Arduino. :), @Tony Sesek