打开DICOM图片(图像内容转换为BMP格式)

很久前写的,也其实就实现一个简单显示的问题,对于“窗位”,“窗宽”的取值问题,以前在CSDN上提问过,却没有得到很好的解决方案。

对与DICOM图片的打开也就实现了,“窗位”,“窗宽”标明的。把显示部分的代码放上来,希望对刚接触DICOM图片格式的人有点帮助,若有高手希望指点下,“窗宽”,“窗位”的取值问题。

我碰到过三种DICOM图片:1.窗位,窗宽的标识位后直接标明直接用就行,2.虽然有值确实一个很大的数值,直接引用显示效果不理想,3、没有标明数值。

代码是VS2003 C++ 写 的:

void CKlsMsgClientDlg::showdicom(CString filepath)//
{
 unsigned char  *m_pDibBits,*m_pDibBits_Save;
 long DicomData,max,min,k,height,width;
 BITMAPINFOHEADER *m_pBIH;
 BITMAPFILEHEADER * m_pB;
 CFile file;
    CFileException fe;
    if (!file.Open(filepath, CFile::modeRead | CFile::shareDenyWrite, &fe))
    {//以“读”的方式打开文件;
        AfxMessageBox("图像文件打不开!");

        return;
    }
 if(GetFileAttributes(filepath)  ==  FILE_ATTRIBUTE_DIRECTORY)
 {
  MessageBox("选择错误");

return;
 }
 DWORD dwDibSize;
 dwDibSize = file.GetLength();
 unsigned char *pDib;
 
 
 pDib = new unsigned char[dwDibSize];
 int w_c= 0;
 int w_w =0;
 try
 {
  if (file.Read(pDib, dwDibSize) != dwDibSize)
  {
   delete []pDib;

return;
  }
 }
 catch (CFileException *e)
 {
  e->Delete();
  delete []pDib;

return;
 }
 unsigned char tag1,tag2,tag3,tag4;
 unsigned char *Info;

 
 DWORD win;
 DWORD winWidth;
 int NameLen;
 unsigned char *Name;

 tag1 = 0xe0;
 tag2 = 0x7f;
 tag3 = 0x10;
 tag4 = 0x00;
 for(int i=0;i< dwDibSize;i++)
 {
  if(*(pDib+i) == tag1 && *(pDib+i+1) == tag2 && *(pDib+i+2) == tag3 && *(pDib+i+3) == tag4)
  {
//   InfoLen = (*(pDib+i+6))*65536+(*(pDib+i+5))*256+(*(pDib+i+4));
   Info = pDib+i+8;
   break;
  }
 }
 dwDibSize -= i;

 tag1 = 0x10;
 tag2 = 0x00;
 tag3 = 0x10;
 tag4 = 0x00;
 for(i=0;i<dwDibSize;i++)
 {
  if(*(pDib+i) == tag1 && *(pDib+i+1) == tag2 && *(pDib+i+2) == tag3 && *(pDib+i+3) == tag4)
  {
   //NameLen = (*(pDib+i+6))*65536+(*(pDib+i+5))*256+(*(pDib+i+4));
   Name = (pDib+i+8);
   break;
  }
 }
 CString sname(Name);
 CClientDC dc(this);
// dc.TextOut(400,10,sname);

 tag1 =0x28;
 tag2 = 0x00;
 tag3 = 0x10;
 tag4 = 0x00;//行数
 for(i=0;i<dwDibSize;i++)
 {
  if(*(pDib+i) == tag1 && *(pDib+i+1) == tag2 && *(pDib+i+2) == tag3 && *(pDib+i+3) == tag4)
  {
   height = (*(pDib+i+9))*256+(*(pDib+i+8));
   break;
  }
 }
 tag1 =0x28;
 tag2 = 0x00;
 tag3 = 0x11;
 tag4 = 0x00;//列数
 for(i=0;i<dwDibSize;i++)
 {
  if(*(pDib+i) == tag1 && *(pDib+i+1) == tag2 && *(pDib+i+2) == tag3 && *(pDib+i+3) == tag4)
  {
   width = (*(pDib+i+9))*256+(*(pDib+i+8));
   break;
  }
 }
 tag1 =0x28;
 tag2 = 0x00;
 tag3 = 0x50;
 tag4 = 0x10;//窗位
 long datesize=0;
 win=0;
 for(int i=0;i<dwDibSize;i++)
 {
  if(*(pDib+i) == tag1 && *(pDib+i+1) == tag2 && *(pDib+i+2) == tag3 && *(pDib+i+3) == tag4)
  {
   NameLen=(*(pDib+i+7))*256+(*(pDib+i+6));
   for(int j = 0;j<NameLen ;j++)
   {
    
    if(*(pDib+i+8+j) == 0x2E)
    {
     break;
    }
    w_c ++;
   }
   for(int j=0;j<w_c;j++)
   {
    win= win + ((*(pDib + i+8+j)-48) * pow(10,(w_c-1-j)));
   }
   break;
  }
 }
 w_c=0;
 /////////////
 tag1 =0x28;
 tag2 = 0x00;
 tag3 = 0x51;
 winWidth=0;
 tag4 = 0x10;//窗宽
 for(i=0;i<dwDibSize;i++)
 {
  if(*(pDib+i) == tag1 && *(pDib+i+1) == tag2 && *(pDib+i+2) == tag3 && *(pDib+i+3) == tag4)
  {
   NameLen=(*(pDib+i+7))*256+(*(pDib+i+6));
   for(int j = 0;j<NameLen ;j++)
   {
    
    if(*(pDib+i+8+j) == 0x2E)
    {
     break;
    }
    w_w ++;
   }
   for(int j=0;j<w_w;j++)
   {
    winWidth= winWidth + ((*(pDib + i+8+j)-48) * pow(10,(w_w-1-j)));
   }
   break;
  }
 }
 w_w=0;
 //if(width>1024)
 //{
 // height = height/4;
 // width = width/4;
 //}
 m_pDibBits = new unsigned char [width*height*3];
 m_pDibBits_Save = new unsigned char[width*height*3];
 m_pBIH = new BITMAPINFOHEADER;
 m_pB = new BITMAPFILEHEADER;
 m_pBIH->biSize = 40;
 m_pBIH->biWidth = width;
 m_pBIH->biHeight = height;
 m_pBIH->biPlanes = 1;
 m_pBIH->biBitCount = 24;
 m_pBIH->biSizeImage = 0;
 m_pBIH->biClrUsed = 0;
 m_pBIH->biClrImportant = 0;
 m_pBIH->biCompression = 0;                            //BI_RGB;
 m_pBIH->biXPelsPerMeter = 3780;
 m_pBIH->biYPelsPerMeter = 3780;
 m_pB->bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
 m_pB->bfReserved1=0;
 m_pB->bfReserved2=0;
 m_pB->bfSize =width*height*3 + (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
 m_pB->bfType=0x4d42;

 max=win+winWidth/2;
 min=win-winWidth/2;
    for(k=0;k<width*height;k++)
 {
  DicomData = (*(Info+k*2))+(*(Info+k*2+1))*256;
  if(DicomData < min)
  {
   *(m_pDibBits+k*3) =   0;
   *(m_pDibBits+k*3+1) = 0;
   *(m_pDibBits+k*3+2) = 0;
  }
  else if(DicomData >max)
  {
   *(m_pDibBits+k*3) = 255;
   *(m_pDibBits+k*3+1) = 255;
   *(m_pDibBits+k*3+2) = 255;
  }
  else
  {
   *(m_pDibBits+k*3) =   (DicomData+winWidth/2-win)*256/winWidth;
   *(m_pDibBits+k*3+1) = (DicomData+winWidth/2-win)*256/winWidth;
   *(m_pDibBits+k*3+2) = (DicomData+winWidth/2-win)*256/winWidth;
  }
 }
 for(int i=0;i<height;i++)
 {
  for(int j=0;j<width*3;j++)
  {
   *(m_pDibBits_Save+height*width*3-width*3-i*width*3+j)=*(m_pDibBits+i*width*3 + j);
  }
 }
 int nSize = sizeof(BITMAPFILEHEADER) + (width*height*3) +40;
 BYTE* pBuffer = new BYTE[nSize];
 memcpy(pBuffer,m_pB,sizeof(BITMAPFILEHEADER));
 memcpy(pBuffer + sizeof(BITMAPFILEHEADER),m_pBIH,40);
 memcpy(pBuffer +sizeof(BITMAPFILEHEADER) +40,m_pDibBits_Save,width*height*3);
 CString sFilePathName = "d:\\AF.bmp";
 CFile PictureFile;
 CFileException e;
 if(PictureFile.Open(sFilePathName, CFile::modeWrite |CFile::modeCreate| CFile::typeBinary, &e))
 {
  PictureFile.Write(pBuffer, nSize) ;
  PictureFile.Close();
  delete [] pBuffer;
 }else
 {
  MessageBox("保存文件出错!");
 }
 m_PicShow.ShowPic(sFilePathName);
 m_csPicPath = sFilePathName;
}

 

你可能感兴趣的:(c,File,delete,byte)