Key Firmware Development Concepts for Embedded Systems
Embedded systems are everywhere, from household appliances to industrial machinery. At the heart of these systems is embedded firmware, the […]
Nowadays, everywhere we look, no matter if it’s a real-life shop or web page, we can see these little, simple and useful, black and white rectangles. Barcodes & QR codes are everywhere, with their usefulness proven over the years.
That is why we decided to create a custom wrapper for Qt QML barcode generation.
In this post, we will show how easy it is to generate and display a barcode and what’s going on behind the scenes in our code.
If you need help with software development services, we encourage you to check our Mobile development services page.
A barcode is a type of visual representation of data, typically printed on products or other items. It is composed of a series of thin and thick vertical lines that encode different characters. Barcodes are a type of machine-readable code that can be used to quickly identify and track products.
They provide quick access to information about an object, such as its price, brand, expiry date, etc. The most common barcode in use today is the Universal Product Code (UPC), which is found on almost all consumer products in the United States. Barcodes have also been used for other purposes such as tracking shipments, inventory management, and asset tagging.
So, to be able to scan or read a barcode (check out our previous blog post about Scanning Barcodes in Qt QML Application) first, you need to generate one.
With the help of fantastic ZXing (Zebra Crossing) barcode image processing library (in this case we mean its port to C++) and Qt framework.
We, at Scythe Studio, created an easy to use library SCodes which can generate and scan barcodes. It can be paired with QML to help us display our result in a simple way no matter the platform we are on.
Here is a little demo of our app, which you can check out at our GitHub:
ZXing-C++ library will help us with barcodes at a lower level. It supports reading and generating many formats of codes but here we will focus on 1-dimensional Code 128 and 2-dimensional QR Code and Data Matrix.
The difference between them in our application is simply the format property because ZXing takes care of all string-to-image conversion.
The library provides a very simple API:
ZXing::MultiFormatWriter class takes a barcode format as constructor’s argument and lets us set encoding, margin, and ECC level (error correction code level)
We call an encode() method of the class mentioned above with our text content and output image size as arguments
It returns BitMatrix where true black pixel and false white pixel of binary barcode image
After we get the bitmap we can process it to image however we like. That’s all there is to it.
Let’s take a look at the code and how it’s done.
First we initialize the MultiFormatWriter class with desired options.
int margin = 1; int eccLevel = 1; ZXing::BarcodeFormat format = ZXing::BarcodeFormat::CODE_128; ZXing::MultiFormatWriter writer = ZXing::MultiFormatWriter(format).setMargin(margin).setEccLevel(eccLevel);
Past the first step. Now that we have set up a writer, it’s time to call an encode() method to give us a bitmap we can work with later.
ZXing::Matrix<uint8_t> bitmap; bitmap = ZXing::ToMatrix<uint8_t>(writer.encode(ZXing::TextUtfEncoding::FromUtf8(“text”), 500, 500));
Our bitmap is ready, so let’s save it as a PNG image. For this, we will use a part of the stb library which is shipped with ZXing.
std::string filepath = “barcode.png”; stbi_write_png(filepath.c_str(), bitmap.width(), bitmap.height(), 1, bitmap.data(), 0);
And it’s done! We have our barcode image.
First, to be able to interact between C++ and QML we need a proper class. It must contain properties of the output image exposed as Q_PROPERTY and a whole class exposed to QML which is done with QML_ELEMENT (available since Qt 5.15.0).
class SBarcodeGenerator: public QQuickItem { Q_OBJECT Q_PROPERTY(int width MEMBER _width NOTIFY widthChanged) Q_PROPERTY(int height MEMBER _height NOTIFY heightChanged) Q_PROPERTY(int margin MEMBER _margin NOTIFY marginChanged) Q_PROPERTY(int eccLevel MEMBER _eccLevel NOTIFY eccLevelChanged) Q_PROPERTY(QString fileName MEMBER _fileName NOTIFY fileNameChanged) Q_PROPERTY(ZXing::BarcodeFormat format MEMBER _format) Q_PROPERTY(QString extension MEMBER _extension) Q_PROPERTY(QString filePath MEMBER _filePath) Q_PROPERTY(QString inputText MEMBER _inputText) #if(QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) QML_ELEMENT #endif … public slots: bool process(const QString & inputString); … signals: void processFinished(); ... private: int _width = 500; int _height = 500; int _margin = 10; int _eccLevel = -1; ZXing::BarcodeFormat _format = ZXing::BarcodeFormat::QR_CODE; QString _extension = "png"; QString _fileName = "barcode"; QString _filePath = ""; QString _inputText = ""; ZXing::Matrix < uint8_t > _bitmap = ZXing::Matrix < uint8_t > (); }
These are the code snippets of our wrapper for displaying purposes. If you want to check out the whole wrapper, head to SCodes repository.
Now for the process function, it’s almost the same code as in case of MultiFormatWriter initialization.
Additionally, we also create path, filename and depending on the extension, we save our image. After everything’s done, we emit a processFinished() signal so QML can do its work.
bool SBarcodeGenerator::process(const QString & inputString) { if (inputString.isEmpty()) { return false; } else { ZXing::MultiFormatWriter writer = ZXing::MultiFormatWriter(_format).setMargin(_margin).setEccLevel(_eccLevel); _bitmap = ZXing::ToMatrix < uint8_t > (writer.encode(ZXing::TextUtfEncoding::FromUtf8(inputString.toStdString()), _width, _height)); _filePath = QDir::tempPath() + "/" + _fileName + "." + _extension; if (_extension == "png") { stbi_write_png(_filePath.toStdString().c_str(), _bitmap.width(), _bitmap.height(), 1, _bitmap.data(), 0); } else if (_extension == "jpg" || _extension == "jpeg") { stbi_write_jpg(_filePath.toStdString().c_str(), _bitmap.width(), _bitmap.height(), 1, _bitmap.data(), 0); } emit processFinished(); return true; } }
Now in the QML part, we start by creating the SBarcodeGenerator object so we can interact with the C++ class.
When we hit the button, the barcodeGenerator will start processing our string (in this case it’s a simple “text”).
After it finishes a signal is sent and our overwritten default signal handler will change the Image’s container source to the generated image and display it.
ApplicationWindow { id: root visible: true width: 500 height: 500 SBarcodeGenerator { id: barcodeGenerator onProcessFinished: { image.source = "file:///" + barcodeGenerator.filePath } } Button { id: generateButton onClicked: { image.source = "" barcodeGenerator.process(qStr(“test”)) } } Image { id: image anchors: parent width: parent.width height: image.width } }
It’s as simple as it gets. Really. Of course, these are snippets, and we skipped some trivial parts of the code, so if you want to see complete and more complex application check out our library SCodes with 2 demos for scanning and generating barcodes.
The numbers on a barcode are unique to the product you’re buying. A standard UPC-A barcode contains 12 digits, each of which holds a specific meaning. The first digit is used as a system identifier to classify the product type.
For instance, 0, 1, 6, 7, and 8 are reserved for standard Universal Product Codes; 2 identifies weighted items such as meat; 3 codes health-related products; 4 is non-food-related items; and 5 and 9 identifies coupons.
Immediately following this first figure are two datasets of five figures that stand for the manufacturer’s number and product identifier, respectively. The last digit is a control code that allows scans to detect errors.
Barcoding does not have a standard format, but it does possess certain characteristics depending on how it is produced. Variations include size, capacity, materials used, linearity, and the need for a checksum.
The size of a barcode usually correlates with the scanning machine and its application, while capacity details the character combinations supported by its particular character set.
Additionally, the width of the narrowest bar indicates density. With regard to linearity, this is determined by the area scanned – a checksum is also included at this point which enhances accuracy through calculations made by scanners when the correct information is retrieved.
Awareness of these various factors will help you identify the necessary barcode type for your use case.
UPC (Universal Product Codes) is one of the most popular barcode types used for labeling retail products. It is found on almost every sale item in the market and all grocery stores in the US and consists of a 12-digit numeric-only number.
GS1 assigns a unique number to each product, making up the first six digits of the barcode, while the manufacturer assigns the next five digits. Each product has its own UPC code that is used for identification.
These codes help digital scanning and tracking of products, and a management software can be used to scan these barcodes to locate mail and packages. This allows users to easily keep track of where their items are and when they will receive them. In addition to UPC codes, other commonly used barcode types include:
Lines of varying widths combine to form barcodes, which can represent up to 10^13 different numbers. There are two main types of barcodes: linear and two-dimensional matrix.
Linear barcodes generate specific patterns, commonly UPC codes, while matrix barcodes look like squares or rectangles with many tiny dots and can contain more data per unit area. Examples include QR codes, EZcode, and Nexcode.
The possibilities for encoding barcodes are endless, meaning the combinations will never be exhausted.
The supported 1D formats by Scythe Studio SCodes for this barcode generation are UPC-A, UPC-E, EAN-8, EAN-13, DataBar (scanning only), Code 39, Code 93, Code 128, Codabar, and ITF (generating only). These are all widely used barcode types used for different purposes.
For 2D formats, QR Codes, DataMatrix, PDF417, and Aztec are currently supported. Both scanning and generating of these formats are possible. MaxiCode is not yet available to use.
Adding new format support to a Qt QML Barcode application is always a work in progress as developers work hard to ensure more types of barcodes can be supported with ease. This makes it convenient for users who need specific barcode types for their respective applications or projects.
Overall, generating barcodes in a Qt QML application has been made simple due to the range of supported formats that allow users to easily scan and generate different types of the barcode within their applications. As new formats become available over time, users will undoubtedly benefit from the convenience this provides them when working with bar codes.
QR codes and barcodes are two common types of computer-readable codes used to quickly store and share data.
The main difference between a QR code and a barcode is that the former has the capacity to store more data than the latter. A typical QR code can hold up to 7,089 characters, while a standard 1D barcode can only fit up to 20 characters at most. As such, QR codes are better suited for storing large amounts of information, such as website links, emails, contact information, or images.
Additionally, while a barcode only stores linear data (vertical lines that each have one character inside), a QR code stores two-dimensional data in both vertical and horizontal directions (black squares arranged at different angles). This allows the code to be scanned from any direction – this is why it’s often called “scannable art.”
Another key difference between a QR code and a barcode is that the former can encode several types of data formats, including URLs, plain text documents, product numbers, NFC tags, binary data (images/audio files), alphanumeric strings (e.g., passwords), etc., with just one scan. Barcodes are limited to numeric digits only, like ISBN numbers or UPCs.
Employing barcoding software in various industries, from healthcare to education, can deliver plenty of advantages. Barcodes make it easier to track and check out products, not to mention the possibility of eliminating manual data entry mistakes or issues caused by misplaced items.
One notable benefit of using barcode software is the ability to prevent data-entry errors, which could potentially lead to substantial business spending over time. Utilizing a QR code scanner means employees do not have to manually key numbers or handwrite them, making the process much faster and more effective.
Another advantage of using barcoding software is reducing employee training time. Thanks to these systems, training only takes a few minutes as employees are only required to understand how the handheld scanner operates and what scanning barcodes entails.
This gives employees less time learning stock lists or pricing, allowing them far more time for work that allows for a greater return on investment for businesses.
The use of barcodes is becoming increasingly popular as businesses look to improve their efficiency and accuracy. By employing this technology, time spent on manual processes can be drastically reduced.
Barcodes provide a secure way to track stock levels in warehouses, eliminating the need for employees to search physically and manually write down inventory numbers. This greatly speeds up the process of finding a particular item or piece of equipment.
Furthermore, barcode software enables companies to serialize their stock easily, with the software recalling information that has been used before. This ensures accuracy when tracking products and equipment quickly and effortlessly.
Additionally, using this technology can save unnecessary costs by avoiding the replacement of lost items and equipment.
Beyond tracking a business’s inventory more effectively, barcodes allow for quicker access to data which promotes better decision-making. This can lead to improved profits from not having to waste precious work time searching for product information and the like.
An added bonus is that barcode software is both affordable and user-friendly, providing a range of data without any difficulty whatsoever.
In conclusion, utilizing the advantages that accompany adopting barcode technology helps ensures a business never faces an inventory crisis or is faced with additional costs due to missing items or data inaccuracies. Increasingly businesses are recognizing its value as it assists in enhancing day-to-day operations and ultimately better long-term functioning too.
Discover how Qt QML projects can help you get the most out of your software development! With Qt, you can create fast, reliable, and responsive software for multiple platforms, including desktop, android, and web applications – all with one single codebase. Enjoy lightning-fast logic and plenty of built-in modules and APIs to provide users with the best experience.
Scythe Studio specializes in cross-platform development – let us take care of creating easy-to-manage, well-documented, and effortlessly maintainable solutions. Get support on any step of the process – from fixing problems, migrating to new versions, and testing code to deploying your app with dedicated installers. Get in touch now and find out how we can help you!
A Quick Response (QR) code is a two-dimensional barcode that encodes data in black and white, or contrasting dark and light, cells arranged in a grid. QR codes are omnidirectional, meaning they can be read from any angle.
The Reed Solomon Correction Method is an algorithm used to generate QR codes. All QR code readers have this built-in as standard, allowing the user to scan even partially covered codes through a good-quality camera.
Several fonts are suitable for usage with Barcodes, such as Bar-Code 39, IDAutomationHC39M, AlphanumericQR, etc.
Using SCodes barcodes and QT codes generator, you can select a barcode content, enter the information you wish to encode into the barcode or QR code, and then get the image on the disk or on the User Interface.
QR stands for “Quick Response,” as these codes allow users to access information instantly when scanned. QR codes are flexible and capable of storing lots of data.
Let's face it? It is a challenge to get top Qt QML developers on board. Help yourself and start the collaboration with Scythe Studio - real experts in Qt C++ framework.
Discover our capabilitiesEmbedded systems are everywhere, from household appliances to industrial machinery. At the heart of these systems is embedded firmware, the […]
Outsourcing embedded systems development has become an increasingly popular strategy for businesses looking to enhance efficiency, reduce costs, and leverage […]
Choosing the right Real-Time Operating System (RTOS) is key to performance, reliability, and efficiency in embedded systems development. This article […]