Thumbnail create logic.

This commit is contained in:
Krad
2022-09-20 09:32:37 +08:00
parent 9673bd9e2b
commit 91ebba6e9d
6 changed files with 49 additions and 65 deletions

View File

@@ -35,27 +35,21 @@ void DICOMPixelDataHelper::FinalizeCodecs() {
#endif #endif
} }
void DICOMPixelDataHelper::GetThumbnailData(ExtendMedicalImageProperties *property, unsigned char* data, void DICOMPixelDataHelper::GetThumbnailData(ExtendMedicalImageProperties *property, void*& data,
unsigned long& length) { unsigned long& length, int & sample) {
double *wlww = property->GetNthWindowLevelPreset(0); double *wlww = property->GetNthWindowLevelPreset(0);
int ww = wlww ? ((int) wlww[0]) : (512); int ww = wlww ? ((int) wlww[0]) : (512);
int wl = wlww ? ((int) wlww[1]) : (256); int wl = wlww ? ((int) wlww[1]) : (256);
int sample = property->GetSamplePerPixel(); sample = property->GetSamplePerPixel();
DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法 DcmFileFormat fileFormat;
if (fileFormat->loadFile(property->GetThumbnailFileName()).good()) { if (fileFormat.loadFile(property->GetThumbnailFileName()).good()) {
DcmDataset *dset = fileFormat->getDataset(); DcmDataset *dset = fileFormat.getDataset();
DicomImage dcmImage(fileFormat, dset->getOriginalXfer()); DicomImage dcmImage(&fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData);
DicomImage *sdcmImage = dcmImage.createScaledImage(100.0, 0.0, 0, 1); dcmImage.setWindow(wl, ww);
sdcmImage->setWindow(wl, ww); length = dcmImage.getOutputDataSize(8);
sdcmImage->showAllOverlays(); data = new unsigned char[length];
length = sdcmImage->getOutputDataSize(8); dcmImage.getOutputData(data, length, 8);//按8位的位宽取数据
unsigned char *outputData = (unsigned char *) sdcmImage->getOutputData(8);//按8位的位宽取数据
data = new unsigned char[length];
memcpy(data, outputData, length);
sdcmImage->deleteOutputData();
delete sdcmImage;
} }
delete fileFormat;
} }

View File

@@ -16,8 +16,8 @@ public:
~DICOMPixelDataHelper() { ~DICOMPixelDataHelper() {
} }
static void GetThumbnailData(ExtendMedicalImageProperties *property, unsigned char* data, static void GetThumbnailData(ExtendMedicalImageProperties *property, void*& data,
unsigned long& length); unsigned long& length,int& sample);
/** /**
* Get Pixel Data with Rescaled, result is calculate as integer, and arrange as integer. * Get Pixel Data with Rescaled, result is calculate as integer, and arrange as integer.
* @param path dcm file absolute path * @param path dcm file absolute path

View File

@@ -2,9 +2,9 @@
#define EXPORTDIALOG_H #define EXPORTDIALOG_H
#include <QDialog> #include <QDialog>
#include "IO/Export/exportoptions.h" #include "Deprecated/Export/exportoptions.h"
#include "qdir.h" #include "qdir.h"
#include "IO/Export/dicomexporterthread.h" #include "Deprecated/Export/dicomexporterthread.h"
#include "QFileDialog" #include "QFileDialog"
#include "IO/DICOM/DicomLoader.h" #include "IO/DICOM/DicomLoader.h"
#include "UI/Widget/ImageView/dicomimageview.h" #include "UI/Widget/ImageView/dicomimageview.h"

View File

@@ -1,8 +1,9 @@
#include "thumbnailImage.h" #include "thumbnailImage.h"
#include <QApplication> #include <QApplication>
#include <QImage>
#include "qstyleoption.h" #include "qstyleoption.h"
#include "qpainter.h" #include "qpainter.h"
#include "IO/DICOM/QDicomUtility.h" #include "IO/DICOM/DICOMPixelDataHelper.h"
static QString unpick_style = "*{background-color:#7f7f7f;}" static QString unpick_style = "*{background-color:#7f7f7f;}"
"QLabel#m_descri{color:white}"; "QLabel#m_descri{color:white}";
@@ -11,6 +12,7 @@ static QString pick_style = "*{background-color:#c5c5c5;}"
"QLabel#m_descri{color:black;}"; "QLabel#m_descri{color:black;}";
thumbnailImage::thumbnailImage(QWidget *parent, ExtendMedicalImageProperties* property) : QFrame(parent) thumbnailImage::thumbnailImage(QWidget *parent, ExtendMedicalImageProperties* property) : QFrame(parent)
,seriesProperty(property)
{ {
this->setObjectName(QString::fromUtf8("frame")); this->setObjectName(QString::fromUtf8("frame"));
@@ -55,9 +57,9 @@ thumbnailImage::thumbnailImage(QWidget *parent, ExtendMedicalImageProperties* pr
m_pixmap->setMaximumSize(QSize(100, 100)); m_pixmap->setMaximumSize(QSize(100, 100));
m_pixmap->setLayoutDirection(Qt::LeftToRight); m_pixmap->setLayoutDirection(Qt::LeftToRight);
m_pixmap->setFrameShape(QFrame::StyledPanel); m_pixmap->setFrameShape(QFrame::StyledPanel);
m_pixmap->setPixmap(DicomUtil::GetThumbnail(property));
m_pixmap->setScaledContents(true); m_pixmap->setScaledContents(true);
m_pixmap->setAlignment(Qt::AlignCenter); m_pixmap->setAlignment(Qt::AlignCenter);
drawThumbnail();
horizontalLayout_2->addWidget(m_pixmap); horizontalLayout_2->addWidget(m_pixmap);
QSpacerItem* horizontalSpacer_3 = new QSpacerItem(6, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); QSpacerItem* horizontalSpacer_3 = new QSpacerItem(6, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer_3); horizontalLayout_2->addItem(horizontalSpacer_3);
@@ -88,7 +90,7 @@ thumbnailImage::thumbnailImage(QWidget *parent, ExtendMedicalImageProperties* pr
m_descri->setText(property->GetSeriesDescription()); m_descri->setText(property->GetSeriesDescription());
m_slicenum->setText(QString("%1").arg(property->GetSliceCount())); m_slicenum->setText(QString("%1").arg(property->GetSliceCount()));
seriesProperty = property;
this->setStyleSheet(unpick_style); this->setStyleSheet(unpick_style);
} }
void thumbnailImage::setHighlight(bool yes) { void thumbnailImage::setHighlight(bool yes) {
@@ -126,5 +128,22 @@ void thumbnailImage::mouseMoveEvent(QMouseEvent *e) {
thumbnailImage::~thumbnailImage() thumbnailImage::~thumbnailImage()
{ {
if (m_Data) free(m_Data);
}
void thumbnailImage::drawThumbnail() {
if (m_Data) free(m_Data);
m_Data = nullptr;
unsigned long length = 0;
int sample = 0;
DICOMPixelDataHelper::GetThumbnailData(seriesProperty, m_Data, length, sample);
QImage image( (uchar*)m_Data, seriesProperty->GetColumns(), seriesProperty->GetRows(),
sample == 1 ? QImage::Format_Grayscale8 : QImage::Format_RGB888);//使用8位深度的灰度图做输出
image = image.scaledToHeight(100);
if (image.width() > 100) image.scaledToWidth(100);
QPixmap pixmap(100, 100);
pixmap.fill(Qt::black);
QPainter p(&pixmap);
p.drawPixmap(50 - image.width() / 2, 50 - image.height() / 2, QPixmap::fromImage(image));
m_pixmap->setPixmap(pixmap);
} }

View File

@@ -30,15 +30,11 @@ protected:
private: private:
void drawThumbnail();
//void setBackgroundColor(QColor pickColor);
QLabel *m_descri; QLabel *m_descri;
QLabel *m_slicenum; QLabel *m_slicenum;
QLabel *m_pixmap; QLabel *m_pixmap;
ExtendMedicalImageProperties* seriesProperty = nullptr; ExtendMedicalImageProperties* seriesProperty = nullptr;
QPoint drag_org_; QPoint drag_org_;
void * m_Data = nullptr;
}; };

View File

@@ -1,42 +1,14 @@
#include "thumbnailbarwidget.h" #include "thumbnailbarwidget.h"
#include "IO/DICOM/DicomLoader.h"
#include "Common/SeriesImageSet.h"
#include <QTimer> #include <QTimer>
#include <QDir>
#include <QDebug> #include <QDebug>
#include <QPixmap> #include <qstyleoption.h>
#include <qpainter.h>
#include "IO/DICOM/DicomLoader.h"
#include "IO/DICOM/DICOMPixelDataHelper.h"
#include "Common/SeriesImageSet.h"
#include "UI/Widget/ImageView/dicomimageview.h" #include "UI/Widget/ImageView/dicomimageview.h"
#include "qstyleoption.h"
#include "qpainter.h"
/************************************************************************
* Function List:
* 1. [Done][Action Open] update thumbnail bar whenever open a directory or file
* 2. [Abort][Click] create a seriesIntance <Copy> showing on chosen DicomImageView
* 3. [Done][Highlight] when the relevant view is clicked,set thumbnail highlight
* 4. [Done][Drag Motion] the same as click
* 5. [Undone][Scroll] scroll bar to show all thumbnails
*
* Consider:
* the difference between action open and click.
* 1. [Done]improve the current map to support multiple instances
* 2. [Done]think about how different instances share the same image data
you may use smart pointer to address this problem, init a instance with another
* 3. [Done]updateThumbnailBar will remove all widget fist which costs high, need to be improved
*
* Notice :
* 1. Drag logic is confused with click, take place of click
*
* Replace Strategy
* 1. file->dir[same series uid] replace all the opening file
* 2. file->file[different instance number] replace all the opening file[Radiant:combine images together]
* 3. dir->dir[same series uid] do nothing
* 4. file->file[same instance number] do nothing
* Namely, existing instances are all dir or same single file
*
/************************************************************************/
class ThumbMessages class ThumbMessages
{ {
@@ -143,6 +115,8 @@ void ThumbnailBarWidget::updateThumbnailBar()
SeriesMapType *series = it_st->second->series; SeriesMapType *series = it_st->second->series;
DICOMPixelDataHelper::InitCodecs();
for (SeriesMapType::const_iterator it_se = series->cbegin(); it_se != series->cend(); it_se++) { for (SeriesMapType::const_iterator it_se = series->cbegin(); it_se != series->cend(); it_se++) {
thumbnailImage *thumbnail = createThumbnailImage(seriesPanel, it_se->second); thumbnailImage *thumbnail = createThumbnailImage(seriesPanel, it_se->second);
@@ -154,6 +128,7 @@ void ThumbnailBarWidget::updateThumbnailBar()
//save all thumbnail in one list //save all thumbnail in one list
LabelList << thumbnail; LabelList << thumbnail;
} }
DICOMPixelDataHelper::FinalizeCodecs();
} }
} }
} }