Skip to main content
BGuth.1
Senior
November 15, 2022
Question

Dynamically generate and display QR code

  • November 15, 2022
  • 8 replies
  • 4490 views

I am using 4.16.1 TouchGFX designer tool. Is it possible to generate QR code for a given string and PIN code in run time and display? Please advice.

This topic has been closed for replies.

8 replies

MM..1
Super User
November 15, 2022
ktrofimo
Senior III
November 15, 2022

I have used https://github.com/ricmoo/QRCode library.

Made a simple wrapper class QRCode.cpp

#include <gui/widgets/qrcode/QRCode.hpp>
#include <gui/widgets/qrcode/qrcode.h>
#include <stdlib.h>
 
QR::QR( const char * text )
{
	 qrcode = new QRCode();
	 qrcodeData = (uint8_t *)malloc( qrcode_getBufferSize(1) );
	 qrcode_initText( qrcode, qrcodeData, 1, 0, text );
}
 
QR::~QR()
{
	free( qrcodeData );
	delete qrcode;
}
 
bool QR::at(uint16_t x, uint16_t y) const
{
 return qrcode_getModule( qrcode, x, y );
}
 
uint16_t QR::getWidth() const
{
 return qrcode->size;
}
 
uint16_t QR::getHeight() const
{
 return qrcode->size;
}

and a custom widget QRCodeWidget.cpp

#include <gui/widgets/qrcode/QRCodeWidget.hpp>
#include <touchgfx/hal/HAL.hpp>
 
QRCodeWidget::QRCodeWidget() : 
 code(0),
 scale(1)
{
}
 
void QRCodeWidget::setQRCode(QR *qrCode)
{
 code = qrCode;
 updateSize();
}
 
void QRCodeWidget::draw(const touchgfx::Rect& invalidatedArea) const
{
 if(!code)
 {
 return;
 }
 
 touchgfx::Rect absolute = getAbsoluteRect();
 
 uint16_t *framebuffer = touchgfx::HAL::getInstance()->lockFrameBuffer();
 
 for(int y = invalidatedArea.y; y < invalidatedArea.bottom(); y++)
 {
 for(int x = invalidatedArea.x; x < invalidatedArea.right(); x++)
 {
 	int offset=0;
 	switch(touchgfx::HAL::DISPLAY_ROTATION)
 	{
 	case touchgfx::rotate0:
 		offset = absolute.x + x + (absolute.y + y) * touchgfx::HAL::DISPLAY_WIDTH;
 		break;
 	case touchgfx::rotate90:
 		offset = (touchgfx::HAL::DISPLAY_WIDTH-(absolute.x + x)-1) * touchgfx::HAL::DISPLAY_HEIGHT
					+ (absolute.y + y);
 		break;
 	}
 		framebuffer[offset] = code->at(x / scale, y / scale) ? 0x0000 : 0xffff;
 
 }
 }
 
 touchgfx::HAL::getInstance()->unlockFrameBuffer();
}
 
touchgfx::Rect QRCodeWidget::getSolidRect() const
{
 return touchgfx::Rect(0,0,getWidth(), getHeight());
}
 
void QRCodeWidget::setScale(uint8_t s)
{
 scale = s;
 updateSize();
}
 
void QRCodeWidget::updateSize()
{
 if(code)
 {
 setWidth(code->getWidth() * scale);
 setHeight(code->getHeight() * scale);
 } 
}

Using is quite straightforward:

#include <gui/common/QrCodeWidget.hpp>
#include <gui/model/QrCode.hpp>
 
QRCodeWidget qrCode;
QR *code;
 
char string[50];
sprintf( string, "http://iwtm.com" );
code = new QR( string );
qrCode.setXY(10,20);
qrCode.setQRCode(code);
qrCode.setScale(8);
add(qrCode);

BGuth.1
BGuth.1Author
Senior
November 15, 2022

Thank you for your reply. I appreciate it. Just so I understand it better, would you mind sharing QrCodeWidget.hpp and QrCode.hpp too please.

ktrofimo
Senior III
November 15, 2022

QRCode.hpp

#ifndef QR_CODE_HPP
#define QR_CODE_HPP
 
#include <touchgfx/hal/Types.hpp>
#include "qrcode.h"
 
/**
* @class QRCode
* 
* @brief An interface for getting the value of a qr code at a particular x,y position
*
* This implementation generates random values for the different x,y coordinates.
* A real qr code will probably save the qr code values in an array like structure and report these instead.
*/
class QR
{
public:
	QR( const char * text );
	~QR();
 /**
 * @fn bool QRCode::at(uint16_t x, uint16_t y);
 *
 * @brief Get the qr code value at a particular coordinate
 *
 * @param x x coordinate
 * @param y y coordinate
 *
 * @return The value of the qr code at the supplied coordinate
 */
 bool at(uint16_t x, uint16_t y) const;
 
 /**
 * @fn uint16_t QRCode::getWidth();
 *
 * @brief Get the width of the qr code
 *
 * @return The width
 */
 uint16_t getWidth() const;
 
 /**
 * @fn uint16_t QRCode::getHeight();
 *
 * @brief Get the height of the qr code
 *
 * @return The height
 */
 uint16_t getHeight() const;
 QRCode *qrcode;
 uint8_t *qrcodeData;
};
 
#endif

QRCodeWidget.hpp

#ifndef QR_CODE_WIDGET_HPP
#define QR_CODE_WIDGET_HPP
 
#include <touchgfx/widgets/Widget.hpp>
#include <gui/model/QRCode.hpp>
#include <touchgfx/hal/Types.hpp>
 
/**
* @class QRCodeWidget
* 
* @brief A widget for displaying a QRCode
* 
* The widget will be drawn in black and white.
* The values of the supplied QRCode will determine the appearance
* The widget can be scaled in order to display the qr code in an appropriate size
*
* @sa touchgfx::Widget
*/
class QRCodeWidget : public touchgfx::Widget
{
public:
 /**
 * @fn QRCodeWidget::QRCodeWidget();
 *
 * @brief Default constructor
 */
 QRCodeWidget();
 
 /**
 * @fn virtual void QRCodeWidget::draw(const touchgfx::Rect& invalidatedArea) const;
 *
 * @brief Draw the part of the qr code that is inside the invalidated area
 * 
 * @param invalidatedArea The region of this drawable that needs to be redrawn
 *
 * @sa touchgfx::Drawable
 */
 virtual void draw(const touchgfx::Rect& invalidatedArea) const;
 
 /**
 * @fn virtual touchgfx::Rect QRCodeWidget::getSolidRect() const;
 *
 * @brief Report this widget as being completely solid
 *
 * @return The solid rect.
 */
 virtual touchgfx::Rect getSolidRect() const;
 
 /**
 * @fn void QRCodeWidget::setQRCode(QRCode *code);
 *
 * @brief Set the qr code to display
 */
 void setQRCode(QR *code);
 
 /**
 * @fn void QRCodeWidget::setScale(uint8_t s);
 *
 * @brief Set the scaling factor of the widget
 */
 void setScale(uint8_t s);
 
private:
 void updateSize();
 
 QR *code;
 uint8_t scale;
};
 
#endif