利用libdmtx 生成 DataMatrix 码
Posted liyuanbhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用libdmtx 生成 DataMatrix 码相关的知识,希望对你有一定的参考价值。
利用 libdmtx 生成 DataMatrix 码
今天比较空闲,研究了 Libdmtx 生成 DM 码的方法。总体是比较简单的。
这里附上代码做个记录。
我的代码用到了 Qt 的 QPainter,没有考虑生成图片的效率问题。如果需要大批量生成 DM 码的图像,可以在 dmtxEncodeDataMatrix 调用之前设置 Libdmtx 的一些参数。这样可以做到dmtxEncodeDataMatrix 生成的数据就已经是图片的实际数据了,只要把数据copy到图像文件中就可以。
我的代码是把相关的功能封装到了一个类。
#ifndef DMCREATOR_H
#define DMCREATOR_H
/**
* @file DMCreator.h
* @author LiYuan
* @email 18069211@qq.com
* @version v1.0
* @license GPL2.0
* @brief libdmtx 库的一个简单封装,用于在 Qt 程序中生成 DM 条形码。
* @details 因为用到了 QPainter 和 QImage, 所以需要 QtGui 模块。
* 可用于 Qt4 和 Qt5 代码中。Qt6 还没有测试。
* @copyright 2015-2022
*/
#include <QString>
#include <QPainter>
#include "dmtx.h"
class DMCreator
public:
DMCreator();
/**
* @brief encodeString 将一个字符串编码为一个DataMatrix 码。采用 UTF-8 编码。
* @param str
* @return
*/
bool encodeString(QString str);
bool encodeString8Bit(QString str); // 采用 Local8Bit 编码方式。
/**
* @brief setColor 设置图像的前景色和背景色,通常为白底黑色码
* @param foreground 前景色,通常为黑色
* @param background 背景色,通常为白色
*/
void setColor(QColor foreground = Qt::black, QColor background = Qt::white);
/**
* @brief renderNoBackground 用于将 DataMatrix 码画到界面上或者画到图像中。只画前景色部分,保留原始的背景。
* @param painter
* @param rect DataMatrix 码所在区域,可以不是正方形。但是最好是正方形。
* @return
*/
bool renderNoBackground(QPainter &painter, QRect rect) const;
bool renderNoBackground(QPainter &painter, int width, int height) const;
/**
* @brief render 用于将 DM 码画到界面上或者画到图像中。用 background 填充背景。
* @param painter
* @param background 背景颜色
* @param foreground 前景颜色
* @param rect DM 码所在区域
* @return
*/
bool render(QPainter &painter,
QColor background,
QColor foreground,
QRect rect = QRect()) const;
/**
* @brief toImage 将 DM 码转化为一个图像。
* @param size 图像的尺寸。
* @return
*/
QImage toImage(QSize size = QSize(0, 0)) const;
/**
* @brief saveImage 将 DM 码图像保存到文件中。
* @param fileName 文件名,需要给出后缀。
* @param size 图像尺寸。
* @return
*/
bool saveImage(QString fileName, QSize size = QSize(0, 0)) const;
/**
* @brief size 获得 DataMatrix 码的长宽。
* @return
*/
QSize size() const;
private:
bool isValid() const;
QColor m_background;
QColor m_foreground;
DmtxEncode * m_enc = nullptr;
;
#endif // DMCREATOR_H
类的实现代码如下:
#include "DMCreator.h"
#include <QDebug>
DMCreator::DMCreator()
:m_background(Qt::white),
m_foreground(Qt::black)
void DMCreator::setColor(QColor foreground, QColor background)
m_background = background;
m_foreground = foreground;
bool DMCreator::encodeString8Bit(QString str)
if(m_enc)
dmtxEncodeDestroy(&m_enc);
m_enc = dmtxEncodeCreate();
assert(m_enc != NULL);
dmtxEncodeSetProp(m_enc, DmtxPropBytesPerPixel, 1);
// dmtxEncodeSetProp(m_enc, DmtxPropBytesPerPixel, 1);
// dmtxEncodeSetProp(m_enc, DmtxPropBytesPerPixel, 1);
dmtxEncodeDataMatrix(m_enc, str.length(), (unsigned char *)str.toLocal8Bit().data());
//int bytesPerPixel = dmtxImageGetProp(m_enc->image, DmtxPropBytesPerPixel);
return true;
bool DMCreator::encodeString(QString str)
if(m_enc)
dmtxEncodeDestroy(&m_enc);
m_enc = dmtxEncodeCreate();
assert(m_enc != NULL);
dmtxEncodeSetProp(m_enc, DmtxPropBytesPerPixel, 1);
qDebug() << str.size();
qDebug() << str.length();
QByteArray ba = str.toUtf8();
dmtxEncodeDataMatrix(m_enc, ba.size(), (unsigned char *)ba.data());
//int bytesPerPixel = dmtxImageGetProp(m_enc->image, DmtxPropBytesPerPixel);
return true;
bool DMCreator::isValid() const
if(!m_enc) return false;
return true;
bool DMCreator::renderNoBackground(QPainter &painter, QRect rect) const
if(!isValid()) return false;
int width = dmtxImageGetProp(m_enc->image, DmtxPropWidth);
int height = dmtxImageGetProp(m_enc->image, DmtxPropHeight);
if(rect.isNull())
rect.setRect(0, 0, width * 4, height * 4);
const double offset_x = rect.left();
const double offset_y = rect.top();
const double scale_x = static_cast<double>(rect.width()) / width;
const double scale_y = static_cast<double>(rect.height()) / height;
int rowSizeBytes = m_enc->image->rowSizeBytes;
int bytesPerPixel = m_enc->image->bytesPerPixel;
for( int y = 0; y < height; y ++)
for(int x = 0; x < width; x ++)
unsigned char b = m_enc->image->pxl[y * rowSizeBytes + x * bytesPerPixel];
if(b == 0)
QRectF r(offset_x + x * scale_x, offset_y + y * scale_y, scale_x, scale_y);
painter.drawRect(r);
return true;
bool DMCreator::renderNoBackground(QPainter &painter, int width, int height) const
QRect rect(0, 0, width, height);
return renderNoBackground(painter, rect);
bool DMCreator::saveImage(QString fileName, QSize size) const
QImage image = toImage(size);
return image.save(fileName);
QSize DMCreator::size() const
int width = dmtxImageGetProp(m_enc->image, DmtxPropWidth);
int height = dmtxImageGetProp(m_enc->image, DmtxPropHeight);
return QSize(width, height);
QImage DMCreator::toImage(QSize size) const
if( !m_enc ) return QImage();
int width = dmtxImageGetProp(m_enc->image, DmtxPropWidth);
int height = dmtxImageGetProp(m_enc->image, DmtxPropHeight);
if(size == QSize(0, 0))
size = QSize(width * 4, height * 4);
QImage image(size, QImage::Format_ARGB32);
QPainter painter(&image);
painter.setBrush(m_background);
painter.setPen(Qt::NoPen);
painter.drawRect(0, 0, size.width(), size.height());
painter.setBrush(m_foreground);
renderNoBackground(painter, size.width(), size.height());
return image;
bool DMCreator::render(QPainter &painter, QColor background, QColor foreground, QRect rect) const
if(!isValid()) return false;
if(rect.isNull())
int width = dmtxImageGetProp(m_enc->image, DmtxPropWidth);
int height = dmtxImageGetProp(m_enc->image, DmtxPropHeight);
rect.setRect(0, 0, width * 4, height * 4);
painter.save();
painter.setPen(Qt::NoPen);
painter.setBrush(background);
painter.drawRect(rect);
painter.setBrush(foreground);
bool ret = renderNoBackground(painter, rect);
painter.restore();
return ret;
这个代码还有很多不完善的地方,比如DM 码有很多参数可以设置。我这代码里都没考虑,用的全都是默认参数。后面有空了我会研究一下有哪些参数比较重要。提供一些接口。
代码使用起来很简单,下面是个简单的例子:
DMCreator dmc;
dmc.encodeString("12345678");
QSize s = dmc.size() * 2;
QImage img = dmc.toImage(s);
生成的图像如下:
下一篇讲讲如何用 Libdmtx 解码 DM 码。
以上是关于利用libdmtx 生成 DataMatrix 码的主要内容,如果未能解决你的问题,请参考以下文章
Data Matrix 二维码解码库 libdmtx 编译方法