ubuntu20.04 Qt6引用dcmtk库实现dicom文件读取和字符集转换
1 环境问题
安装完Qt6,新建Qt/QtQuick CMake工程编译出现如下错误:
Found package configuration file: Qt6Config.cmake but it set Qt6 FOUND to FALSE so package "Qt6" is considered to be NOT FOUND.
原因:
这是因为系统中缺少OpenGL库,可以安装libgl1-mesa-dev
解决方法:
sudo apt install libgl1-mesa-dev
项目编译成功后运行,如果出现如下错误:
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even through it was found.
sudo apt install libxcb-cursor*
2 引用dcmtk
由于作者使用cmake编译,所以需要使用CMakeLists添加第三方库的方式,来引用dcmtk库。
set(DCMTK_INC_DIR "/home/charles/workdir/software/dcmtk-3.6.8/dcmtk-3.6.8-release/include")
set(DCMTK_LIB_DIR "/home/charles/workdir/software/dcmtk-3.6.8/dcmtk-3.6.8-release/lib")
include_directories(${DCMTK_INC_DIR})
link_directories(${DCMTK_LIB_DIR})
target_link_libraries(dcmtk-test PUBLIC
Qt${QT_VERSION_MAJOR}::Widgets
${DCMTK_LIB_DIR}/libdcmtk.so
)
3 测试程序
实现对dicom tag值的读取,以及字符集的转换。以支持中文或其他字符的显示
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <dcmtk/dcmdata/dctk.h>
#include <dcmtk/ofstd/ofchrenc.h>
bool strEqual(const string s, const string s1)
{
return (strcmp(s.c_str(), s1.c_str()) == 0);
}
//参考https://dicom.nema.org/medical/dicom/current/output/chtml/part18/chapter_D.html
string getCodeName(const string &Ch)
{
if (strEqual(Ch, "GB18030"))
return "GB18030";
else if (strEqual(Ch, "ISO_IR 192"))
return "UTF-8";
else if (strEqual(Ch, "ISO_IR 100"))
return "ISO-8859-1";
else if (strEqual(Ch, "ISO_IR 101"))
return "ISO-8859-2";
else if (strEqual(Ch, "ISO_IR 109"))
return "ISO-8859-3";
else if (strEqual(Ch, "ISO_IR 110"))
return "ISO-8859-4";
else if (strEqual(Ch, "ISO_IR 144"))
return "ISO-8859-5";
else if (strEqual(Ch, "ISO_IR 127"))
return "ISO-8859-6";
else if (strEqual(Ch, "ISO_IR 126"))
return "ISO-8859-7";
else if (strEqual(Ch, "ISO_IR 138"))
return "ISO-8859-8";
else if (strEqual(Ch, "ISO_IR 148"))
return "ISO-8859-9";
else if (strEqual(Ch, "ISO_IR 203"))
return "ISO-8859-15";
else if (strEqual(Ch, "ISO_IR 166"))
return "TIS-620";
else if (strEqual(Ch, "ISO 2022 IR 13") || strEqual(Ch, "ISO 2022 IR 87"))
return "ISO-2022-JP";
else if (strEqual(Ch, "ISO 2022 IR 6")|| strEqual(Ch, "ISO 2022 IR 149"))
return "ISO-2022-KR";
else if (strEqual(Ch, "ISO 2022 IR 6")|| strEqual(Ch, "ISO 2022 IR 58"))
return "ISO-2022-CN";
else if (strEqual(Ch, "GBK"))
return "GBK";
else
return "";
}
OFString toUTF8(OFString &curEncoding,OFString &valStr)
{
OFCharacterEncoding encoding;
OFCondition res = encoding.selectEncoding(getCodeName(curEncoding.c_str()).c_str(), OFString("UTF-8"));
OFString toString("");
res = encoding.convertString(valStr, toString);
return toString;
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
loadDcm();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::loadDcm()
{
DcmFileFormat fileformat;
OFCondition status = fileformat.loadFile("./test.dcm");
if (status.good())
{
OFString str;
OFString charset("GB18030");
if (fileformat.getDataset()->findAndGetOFString(DCM_SpecificCharacterSet, str).good())
{
charset = str;
ui->textEdit->append(QString::fromStdString(str.c_str()));
}
if (fileformat.getDataset()->findAndGetOFString(DCM_PatientName, str).good())
ui->textEdit->append(QString::fromUtf8(toUTF8(charset,str).c_str()));
if (fileformat.getDataset()->findAndGetOFString(DCM_PatientID, str).good())
ui->textEdit->append(QString::fromUtf8(toUTF8(charset,str).c_str()));
if (fileformat.getDataset()->findAndGetOFString(DCM_BodyPartExamined, str).good())
ui->textEdit->append(QString::fromUtf8(toUTF8(charset,str).c_str()));
if (fileformat.getDataset()->findAndGetOFString(DCM_PatientPosition, str).good())
ui->textEdit->append(QString::fromUtf8(toUTF8(charset,str).c_str()));
}
else
ui->textEdit->append("Bad file!");
}
执行效果如图: