接上节内容,在项目上添加了读取图片并解码的程序,并且定位二维码位置;
基于qt和libdmtx库生成DataMatrix的工程,
DataMatrix开源的编码及识别库libdmtx的github:https://github.com/dmtx/libdmtx;
我用qt写的完整工程在:https://github.com/abcvincent/dmtxMaker;
github->doc中有DataMatrix国际标准文件和知乎的详解QR码的文档;
效果如下:
其中红线标注的是二维码的L边;
先贴出libdmtx库里的例子:
/* 3) DECODE the Data Matrix barcode from the copied image */
img = dmtxImageCreate(pxl, width, height, DmtxPack24bppRGB);//创建dmtxImage
assert(img != NULL);
dec = dmtxDecodeCreate(img, 1);//解码img
assert(dec != NULL);
reg = dmtxRegionFindNext(dec, NULL);//查找下一个?
if(reg != NULL) {
msg = dmtxDecodeMatrixRegion(dec, reg, DmtxUndefined);//获取解码信息
fprintf(stdout, "msg->arraySize : \"%d\"\n", msg->arraySize );
fprintf(stdout, "msg->codeSize : \"%d\"\n", msg->codeSize );
fprintf(stdout, "msg->outputSize: \"%d\"\n", msg->outputSize);
int oned = sqrt(msg->arraySize);//开方,求数据大小,然后把数据列输出来
for (int i=0; i<msg->arraySize; i++){
fprintf(stdout, " %c.", msg->array[i]);
if (i%oned==oned-1){
fprintf(stdout, "\n");
}
}
fprintf(stdout, "\n\n");
for (int j=0; j<msg->codeSize; j++){
fprintf(stdout, " %c.", msg->code[j]);
}
fprintf(stdout, "\n\n");
for (int k=0; k<msg->outputSize; k++){
fprintf(stdout, " %c.", msg->output[k]);
}
fprintf(stdout, "\n\n");
if(msg != NULL) {
fputs("output: \"", stdout);
fwrite(msg->output, sizeof(unsigned char), msg->outputIdx, stdout);//读取信息并存储
fputs("\"\n", stdout);//输出解码信息
dmtxMessageDestroy(&msg);
}
dmtxRegionDestroy(®);
}
dmtxDecodeDestroy(&dec);
dmtxImageDestroy(&img);
free(pxl);
fprintf(stdout, "%d\n", getSizeIdxFromSymbolDimension(12, 12));
qt使用的时候需要将图片转成 DmtxImage格式;
具体如下:
void dataMatrixDecode()
{
//简化版本
QTime time;
QImage src("D:/1.jpg");//路径
DmtxMessage *msg;
DmtxRegion *reg;
DmtxImage *imgdtx;
QString outstr;
time.start();//qt开始计时
qDebug()<<"src.format() "<<src.format();//注意图片格式要对应 dmtxImageCreate的 不然无法解码
// 增加超时时间。
DmtxTime beginTime = dmtxTimeNow(); // 根据系统设置情况,获得当前时间
long timeout_ms = 200;
DmtxTime stopTime = dmtxTimeAdd(beginTime, timeout_ms); // 增加xx ms
//创建dmtxImage,将qt读取到的图片存储到dmtxImage
imgdtx = dmtxImageCreate(src.bits(),src.width(),src.height(),DmtxPack32bppXRGB);
assert(imgdtx != NULL);
DmtxDecode *dec = dmtxDecodeCreate(imgdtx, 1);//解码
assert(dec != NULL);
reg = dmtxRegionFindNext(dec,&stopTime);//查找下一个,如果超时则认为没有找到
assert(reg != NULL);
if(dmtxTimeExceeded(stopTime))
{
qDebug()<<"超时";
}
else
{
if (reg != NULL)
{
msg = dmtxDecodeMatrixRegion(dec, reg, DmtxUndefined);//获取解码信息
if (msg != NULL)
{
cout << msg->output << endl;//输出解码信息
cout << msg->outputIdx << endl;
//qt输出解码信息string->QString
string strout = (char*)msg->output;//解码信息
outstr=QString::fromStdString(strout);
qDebug()<<"解码信息:"<<outstr;//解码信息
qDebug()<<"解码信息xx:"<<msg->output;//解码信息
//二维码坐标信息
qDebug()<<"reg->leftLine.locPos.X "<<reg->leftLine.locPos.X;
qDebug()<<"reg->leftLine.locPos.Y "<<reg->leftLine.locPos.Y;
qDebug()<<"reg->leftLine.locNeg.X "<<reg->leftLine.locNeg.X;
qDebug()<<"reg->leftLine.locNeg.Y "<<reg->leftLine.locNeg.Y;
qDebug()<<"bottomLine.locPos.X "<<reg->bottomLine.locPos.X;
qDebug()<<"bottomLine.locPos.Y "<<reg->bottomLine.locPos.Y;
qDebug()<<"bottomLine.locNeg.X "<<reg->bottomLine.locNeg.X;
qDebug()<<"bottomLine.locNeg.y "<<reg->bottomLine.locNeg.Y;
dmtxMessageDestroy(&msg);
}
else{qDebug()<<"无法检测到2";}
dmtxRegionDestroy(®);
}
else{qDebug()<<"无法检测到1";}
}
dmtxDecodeDestroy(&dec);
dmtxImageDestroy(&imgdtx);
qDebug()<<time.elapsed()/1000.0<<"s";
}
原图如下: