关闭

把DICOM文件中的图像部分提取到BMP文件的函数

标签: etagcompressionfpimagedomainbuffer
2188人阅读 评论(1) 收藏 举报
分类:

首先建立一个对话框矿类CDicomBMPDlg ,然后写函数

void CDicomBMPDlg::ConvertDicomToBMP()
{

 short int nCols = 0, nRows = 0;
    short int nBitsAllocated, nSamplesPerPixel = 1;
 short int nHighBit = 0;
 float fWindowWidth = 0, fWindowCenter = 0 , fRescaleSlope = 1, fRescaleIntercept = 0;
 BOOL bIsSigned = FALSE;

 BOOL bGroup2Done = FALSE, bGroup28Done = FALSE, bPixelDataDone = FALSE;

 int nBytesP = 0;
 int nFrameSize = 0;
 long int nLength;
 const char *pszFileName = m_strFileName.GetBuffer(3);
 char szPhotometric[32]="", szTemp[32]="", szTransferSyntaxUID[80]="";

 BOOL bImplicitVR = TRUE;
 COMPRESSION_MODE nCompressionMode = COMPRESS_NONE;
 DATA_ENDIAN nDataEndian = LITTLE_ENDIAN;
 int i;
 int nBytes;


   FILE *fp;
   char *pData = 0;
   short int gTag, eTag;
   int nNumFrames = 1;

   fp = fopen(pszFileName, "rb");
   if (!fp)
    {
       AfxMessageBox("Failed to open file for read.");
       return;
    }

    while(fread(&gTag, sizeof(short), 1, fp) == 1)
    {
    if (nDataEndian == BIG_ENDIAN)
   SwapWord((char *) &gTag, 1);

      switch(gTag)
      {
    case 0x0002: // Meta header.

   if (bGroup2Done)
      break;

   fread(&eTag, sizeof(short), 1, fp);
   // Meta header is always in Little Endian Explicit VR syntax.
         switch(eTag)
          {
             case 0x0010: // Transfer syntax UID
     if (readString(fp, szTransferSyntaxUID, FALSE, LITTLE_ENDIAN) != 0)
      break;

    // Check data endian.
    if (!strcmp(szTransferSyntaxUID, "1.2.840.10008.1.2.2")) // Explicit VR Big Endian
     nDataEndian = BIG_ENDIAN; // Big Endian
    else
     nDataEndian = LITTLE_ENDIAN; // Little Endian

    // Check if it is implicit VR or Explicit VR
    if (!strcmp(szTransferSyntaxUID, "1.2.840.10008.1.2")) // Implicit VR Little Endian
     bImplicitVR = TRUE; // Implicit VR
    else
     bImplicitVR = FALSE; // Explicit VR

    // Parse the encapsulation/compression
    if (!strcmp(szTransferSyntaxUID, "1.2.840.10008.1.2.4.50")) // JPEG lossy
     nCompressionMode = COMPRESS_JPEGLOSSY;
    else if (!strcmp(szTransferSyntaxUID, "1.2.840.10008.1.2.4.51")) // JPEG lossy 12bit
     nCompressionMode = COMPRESS_JPEGLOSSY12BIT;
    else if (!strcmp(szTransferSyntaxUID, "1.2.840.10008.1.2.4.70")) // JPEG lossless first order prediction
     nCompressionMode = COMPRESS_JPEGLOSSLESS;
    else if (!strcmp(szTransferSyntaxUID, "1.2.840.10008.1.2.4.57")) // JPEG lossless process 14
     nCompressionMode = COMPRESS_JPEGLOSSLESS2;
    else if (!strcmp(szTransferSyntaxUID, "1.2.840.10008.1.2.5")) // RLE
     nCompressionMode = COMPRESS_RLE;

    bGroup2Done = TRUE;

   break;

   }
   break;

       case 0x0008: // First non-Meta group
         fread(&eTag, sizeof(short), 1, fp);
       if (nDataEndian == BIG_ENDIAN)
      SwapWord((char *) &eTag, 1);

   if ((eTag == 0x0005) || (eTag == 0x0008))
    bGroup2Done = TRUE;
   break;

       case 0x0028: // Image pixel data info group
         fread(&eTag, sizeof(short), 1, fp);

   if (bGroup28Done)
      break;

       if (nDataEndian == BIG_ENDIAN)
      SwapWord((char *) &eTag, 1);

         switch(eTag)
          {
            case 0x0002: // Samples per Pixel
    nSamplesPerPixel = readUS(fp, nDataEndian);
               break;

            case 0x0004:  // Photometric Interpolation
    readString(fp, szPhotometric, bImplicitVR, nDataEndian);
               break;

            case 0x0008:  // Number of frames
    nNumFrames = readIS(fp, bImplicitVR, nDataEndian);
               break;

             case 0x0010: // Rows
      nRows = readUS(fp, nDataEndian);
               break;

            case 0x0011: // Columns
      nCols = readUS(fp, nDataEndian);
               break;

            case 0x0100: // Bits allocated
      nBitsAllocated = readUS(fp, nDataEndian);
               break;

   case 0x0102: // High bit
    nHighBit = readUS(fp, nDataEndian);
    break;

   case 0x0103: // Is signed?
    bIsSigned = readUS(fp, nDataEndian);
    break;

   case 0x1050: // Window Center
    fWindowCenter = readDS(fp, bImplicitVR, nDataEndian);
    break;

   case 0x1051: // Window Width
    fWindowWidth = readDS(fp, bImplicitVR, nDataEndian);
    break;

   case 0x1052: // Rescale intercept
    fRescaleIntercept = readDS(fp, bImplicitVR, nDataEndian);
    break;

   case 0x1053: // Rescale slope
    fRescaleSlope = readDS(fp, bImplicitVR, nDataEndian);
    bGroup28Done = TRUE;
    break;

   default:
    // do nothing
    break;
           }
         break;
        case 0x7fe0:
         fread(&eTag, sizeof(short), 1, fp);
   if (bPixelDataDone)
    break;

       if (nDataEndian == BIG_ENDIAN)
      SwapWord((char *) &eTag, 1);

         if (eTag == 0x0010)
         {
    nBytesP = nSamplesPerPixel*nBitsAllocated/8;
    nFrameSize = nCols * nRows * nBytesP;
    nLength = nNumFrames * nFrameSize;

    // Don't try to parse grup 2 and group 28 any more
    bGroup2Done = TRUE;
    bGroup28Done = TRUE;

    // Parse pixel data
    switch(nCompressionMode)
    {
    case COMPRESS_NONE:
     pData = new char[nLength + 16];
     fseek(fp, 4, SEEK_CUR); // Skip 4 bytes (length bytes)
     nBytes = fread(pData, 1, nLength, fp);

     if (nBytes != nLength)
     {
      AfxMessageBox("Failed to read all pixel data.");
     }
     bPixelDataDone = TRUE;
     break;

    case COMPRESS_RLE:
     AfxMessageBox("RLE compression not supported at this moment");
     // To do: 
     //   1. Read the offset table.
     //   2. Read and uncompress RLE image frames into either RGB or monochrome format.
     //   3. Put frames in the pData buffer, one frame after another.
     //  Public domain RLE decompression source code is in Papyrus and dcmtk.
     break;
    case COMPRESS_JPEGLOSSY:
     AfxMessageBox("JPEG lossy compression not supported at this moment");
     // To do: 
     //   1. Read the offset table
     //   2. Read and uncompress JPEG image frames into either RGB or monochrome format.
     //   3. Put frames in the pData buffer, one frame after another.
     //  Public domain JPEG decompression source code is in Papyrus and dcmtk.
     break;
    case COMPRESS_JPEGLOSSY12BIT:
     AfxMessageBox("JPEG lossy 12-bit compression not supported at this moment");
     // To do: 
     //   1. Read the offset table
     //   2. Read and uncompress JPEG image frames into either RGB or monochrome format.
     //   3. Put frames in the pData buffer, one frame after another.
     //  Public domain JPEG decompression source code is in Papyrus and dcmtk.
     break;
    case COMPRESS_JPEGLOSSLESS:
    case COMPRESS_JPEGLOSSLESS2:
     AfxMessageBox("JPEG lossless compression not supported at this moment");
     // To do: 
     //   1. Read the offset table
     //   2. Read and uncompress JPEG image frames into either RGB or monochrome format.
     //   3. Put frames in the pData buffer, one frame after another.
     //  Public domain JPEG decompression source code is in Papyrus and dcmtk.
     break;
    }

         }
         break;
   }

   if (pData)
    break; // We are done.
    }

  fclose(fp);

  if (pData) // Have we got the pixel data?
  {
   // Need to do byte swap?
   if (nDataEndian == BIG_ENDIAN)
   {
    if (nBitsAllocated > 8)
   SwapWord(pData, nLength/2);
   }

   if (nBitsAllocated > 8)
   {
    // We need to convert it to 8-bit.
    char *pNewData;

    pNewData = convertTo8Bit(pData, nLength/2, bIsSigned, nHighBit,
     fRescaleSlope, fRescaleIntercept, fWindowCenter, fWindowWidth);

    // Use the new 8-bit data.
    if (pNewData)
    {
     delete [] pData;
     pData = pNewData;
     nBytesP = 1;
     nFrameSize /= 2;

     nLength /= 2;
    }
   }

   // Write BMP files
   for (i = 0; i < nNumFrames; i++)
  WriteBMPFile(pData + nFrameSize*i, nFrameSize, nCols, nRows, nBytesP, szPhotometric, i+1);

   // Free the memory.
   delete [] pData;

   AfxMessageBox("Images successfully converted into BMP.");

  }

}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:35492次
    • 积分:592
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:3篇
    • 译文:0篇
    • 评论:25条
    文章分类
    最新评论