dcmtk和wxWidgets混合编程

来源:互联网 发布:剑三炮哥脸型数据 编辑:程序博客网 时间:2024/04/29 13:22

环境:IDE:vc6.0 OS:xp

一、库编译、安装

a、wx库的编译、安装可以参考上一篇中所写。就没有问题的。

b、dcmtk库的编译、安装

1、首先当然是要下载库源文件了,这些在官方网站上都可以下,下载源文件和支持库即可。解压后,就会发现有个CMakelist.txt文件,一看就知道要用cmake生成工程文件了。所以,这所有的前提是你下载了cmake,并且会用cmake

因为wx的run_time library要在Debug Multithreaded dll下运行,所以先将CMakelist文件中的MTd和MT全都换成MDd和MD。

2、打开cmake设置好源路径和安装路径,点击configure,这时,就会出现一些选项,设置好这些选项,像库的安装路径,是否需要支持库,需要的话就要找到这些库的路径。都设置完后,再点击config,点击ok,这时有个警告,这个警告时cmake版本问题,应该是问题不大的。

3、cmake完成后,在设置的安装路径下面,就可以看到dcmtk的工程文件,用vc6打开,将run_time library设置为Debug Multithreaded dll,编译,这时如果出现LINK2005错误,与下面类似:

 

Linking...

MSVCRTD.LIB(MSVCRTD.dll) : error LNK2005: __errno already defined in LIBCMTD.LIB(dosmap.obj)

MSVCRTD.LIB(MSVCRTD.dll) : error LNK2005: _free already defined in LIBCMTD.LIB(dbgheap.obj)

MSVCRTD.LIB(MSVCRTD.dll) : error LNK2005: _realloc already defined in LIBCMTD.LIB(dbgheap.obj)

MSVCRTD.LIB(MSVCRTD.dll) : error LNK2005: _malloc already defined in LIBCMTD.LIB(dbgheap.obj)

MSVCRTD.LIB(MSVCRTD.dll) : error LNK2005: _memmove already defined in LIBCMTD.LIB(memmove.obj)

4、解决办法:a、可以在link-》input中将上面的库设置为忽略库,即:MSVCRTD.LIB。b、按着这种顺序MSVCRTD.LIB LIBCMTD.LIB添加这两种库。c、上面两种方法结合,先按顺序添加,再忽略。这样就可以解决LNK2005的错误。

5、编写实际例子,这写例子前,先说下,程序写完后,编译,可能会出现两个库的宏定义冲突了。警告时没有关系的,主要是有一个错误:ssize_t两次定义的类型不同,这个问题的解决方法是,只需要将其中一个库的源文件中的ssize_t的定义注释掉就可以了。这里只给出两个主要类的代码:

类DcmReader

 

#include "DcmReader.h"

#include "myDcm.h"

#include "dcmtk/dcmimgle/dcmimage.h"

#include "dcmtk/dcmdata/dcfilefo.h"

#include "dcmtk/dcmdata/dcdeftag.h"

#define DEFAULTDEPTH 8

DcmReader::DcmReader(void)

{

m_image=NULL;

 

isOpen=false;

}

 

DcmReader::~DcmReader(void)

{

Clear();

}

 

bool DcmReader::Open(const char*  fileName)

{

if(!isOpen){

m_image=new DicomImage(fileName);

if(m_image!=NULL){

if(m_image->getStatus()==EIS_Normal){

if(m_image->isMonochrome()){

m_image->setMinMaxWindow();

m_image->getWindow(wcenter,wwidth);

m_fileformat=new DcmFileFormat();

OFCondition status=m_fileformat->loadFile(fileName);

if(status.good()){

//OFString pat

}

isOpen=true;

 

 

}

}else{

delete m_image;

}

}

}

else{

return false;

}

 

return isOpen;

}

 

const unsigned char* DcmReader::getData(void)

{

if(isOpen){

return (const unsigned char*)m_image->getOutputData(DEFAULTDEPTH);

}

return NULL;

}

 

void DcmReader::Clear(void)

{

if(isOpen){

delete m_fileformat;

delete m_image;

isOpen=false;

}

}

/*

int DcmReader::getData(void* buffer,size_t size)

{

if(isOpen){

return m_image->getOutputData(buffer,size,DEFAULTDEPTH);

}

 

return 0;

}*/

 

int DcmReader::getDataSize(void) const

{

if(isOpen)

return m_image->getOutputDataSize(DEFAULTDEPTH);

return 0;

}

 

int DcmReader::getWidth(void)const

{

if(isOpen)

return m_image->getWidth();

return 0;

}

 

int DcmReader::getHeight(void)const

{

if(isOpen)

return m_image->getHeight();

return 0;

}

 

int DcmReader::getDepth(void)const

{

if(isOpen)

return m_image->getDepth();

return 0;

}

 

bool DcmReader::isOpened(void)

{

return isOpen;

}

 

void DcmReader::getWindow(double& c,double& w){

m_image->getWindow(c,w);

}

void DcmReader::setWindow(double c,double w){

wcenter=c;

wwidth=w;

m_image->setWindow(c,w);

}

void DcmReader::addWindowWidth(double step){

wwidth+=step;

m_image->setWindow(wcenter,wwidth);

}

void DcmReader::addWindowCenter(double step){

wcenter+=step;

m_image->setWindow(wcenter,wwidth);

}

 

/*

long DcmReader::createDIB(void* buffer, size_t size)

{

 

return m_image->createWindowsDIB(buffer,size,0,8);

}

*/

 

void DcmReader::getPatientName(char* buffer,int len)

{

OFString patientName;

if(m_fileformat->getDataset()->findAndGetOFString(DCM_PatientsName,patientName).good()){

strncpy(buffer,patientName.c_str(),len);

}

}



类wxDcmCanvas
#include "wxDcmCanvas.h"

#include "app.h"
#define DEFAULTFILE  wxT("E://dicom//dcm//CR-MONO1-10-chest.dcm")

BEGIN_EVENT_TABLE(wxDcmCanvas, wxScrolledWindow)
//EVT_MOTION(ShapedFrame::OnMouseMove)
EVT_PAINT(wxDcmCanvas::OnPaint)
END_EVENT_TABLE()

wxDcmCanvas::wxDcmCanvas(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size)
:wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER )
{
SetScrollbar(10,10,5,10);
SetClientSize(300,300);
}

wxDcmCanvas::~wxDcmCanvas(void)
{
reader.Clear();
}

void wxDcmCanvas::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc( this );
PrepareDC( dc );
if(m_bitmap.Ok())
dc.DrawBitmap(m_bitmap,0,0);

}

bool wxDcmCanvas::OnOpen(wxString fileName)
{
const wxChar* src=fileName.c_str();
char f[256];
wxConvCurrent->WC2MB(f,src,256);
if(reader.isOpened()){
reader.Clear();
}
if(reader.Open(f)){
reader.getPatientName(f,256);
wxChar name[256];
wxConvCurrent->MB2WC(name,f,256);
wxLogDebug(wxT("patient name:%s"),name);
updateBitmap();
Refresh();
return true;
}
else{
wxLogMessage(_("Open %s failed"),fileName.c_str());
}

return false;
}

bool wxDcmCanvas::updateBitmap(void)
{
if(reader.isOpened()){
int w =reader.getWidth(), h = reader.getHeight();
//wxGetApp().getFrame()->SetClientSize(w>1280?1280:w,h>1024?1024:h);
//SetScrollbars( 10, 10, w/10, h/10);
wxImage image=wxImage(w,h);

unsigned char *data = image.GetData();
const unsigned char *src=reader.getData();
size_t pos,posS;
for(int i=0;i<h;++i)
for(int j=0;j<w;++j){
posS=i*w+j;
pos=posS*3;
data[pos]=data[pos+1]=data[pos+2]=src[posS];
}
wxSize s=GetClientSize();
if(w>h)
image.Rescale(s.GetWidth(),h*s.GetWidth()/w);
else{
image.Rescale(w*s.GetHeight()/h,s.GetHeight());
}
m_bitmap=wxBitmap(image);
return true;
}
else{
return false;
}
}

DcmReader* wxDcmCanvas::getDoc(void)
{
return &reader;

}

bool wxDcmCanvas::saveToFile(wxString fileName, int type)
{
if(m_bitmap.Ok()){
wxImage image=m_bitmap.ConvertToImage();
return image.SaveFile(fileName);
}
return false;
}