首先建立一个对话框矿类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.");
}
}