单帧dcm文件
public static void ConvertDicomToBmp(string dicomFilePath, string bmpOutputPath)
{
DicomFile dcmFile = DicomFile.Open(dicomFilePath);
var name = dcmFile.Dataset.GetString(DicomTag.PatientName);
ushort bitStored = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.BitsStored);
ushort bitAllocated = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.BitsAllocated);
ushort samplesPerPixel = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.SamplesPerPixel);
ushort width = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.Columns);
ushort height = dcmFile.Dataset.GetSingleValue<ushort>(DicomTag.Rows);
int windowCenter; //窗口中心
if (!dcmFile.Dataset.TryGetSingleValue(DicomTag.WindowCenter, out windowCenter))
{
windowCenter = 0; // 默认值
}
int windowWidth; //窗口宽度
if (!dcmFile.Dataset.TryGetSingleValue(DicomTag.WindowWidth, out windowWidth))
{
windowWidth = 0; // 默认值
}
string modality; //模态信息
if (!dcmFile.Dataset.TryGetString(DicomTag.Modality, out modality))
{
modality = "Unknown"; // 默认值或处理方式
}
Bitmap gdiImg = new Bitmap(width, height);
if (bitStored > 8) //处理高位深度图像,数据用两个字节ushort表示
{
ushort[] pixelData = dcmFile.Dataset.GetValues<ushort>(DicomTag.PixelData);
ushort maxVal = pixelData.Max();
ushort minVal = pixelData.Min();
double compressFactor = byte.MaxValue / (double)(maxVal - minVal) - 0.00000000001;
if (samplesPerPixel == 1) // Gray
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
double gray = pixelData[i * width + j];
int grayGDI = (int)(gray * compressFactor);
grayGDI = grayGDI < 0 ? 0 : (grayGDI > 255 ? 255 : grayGDI);
Color color = Color.FromArgb(grayGDI, grayGDI, grayGDI);
gdiImg.SetPixel(j, i, color);
}
}
gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
}
else if (samplesPerPixel == 3) // RGB
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int index = (i * width + j) * 3;
ushort r = pixelData[index];
ushort g = pixelData[index + 1];
ushort b = pixelData[index + 2];
// 压缩 RGB 值到 0-255 范围
int rGDI = (int)(r * compressFactor);
int gGDI = (int)(g * compressFactor);
int bGDI = (int)(b * compressFactor);
rGDI = rGDI < 0 ? 0 : (rGDI > 255 ? 255 : rGDI);
gGDI = gGDI < 0 ? 0 : (gGDI > 255 ? 255 : gGDI);
bGDI = bGDI < 0 ? 0 : (bGDI > 255 ? 255 : bGDI);
Color color = Color.FromArgb(rGDI, gGDI, bGDI);
gdiImg.SetPixel(j, i, color);
}
}
gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
}
}
else //处理低位深度图像,数据用一个字节byte表示
{
byte[] pixelData = dcmFile.Dataset.GetValues<byte>(DicomTag.PixelData);
if (samplesPerPixel == 1) // Gray
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
byte gray = pixelData[i * width + j];
Color color = Color.FromArgb(gray, gray, gray);
gdiImg.SetPixel(j, i, color);
}
}
gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
}
else if (samplesPerPixel == 3) // RGB
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int index = (i * width + j) * 3;
byte r = pixelData[index];
byte g = pixelData[index + 1];
byte b = pixelData[index + 2];
Color color = Color.FromArgb(r, g, b);
gdiImg.SetPixel(j, i, color);
}
}
gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
}
}
Console.WriteLine("BMP 文件已保存到 " + bmpOutputPath);
}
多帧dcm文件转化
public static void ConvertDicomToBmps(string dicomFilePath, string bmpOutputFolder)
{
DicomFile dcmFile = DicomFile.Open(dicomFilePath);
var dataset = dcmFile.Dataset;
string name = dataset.GetString(DicomTag.PatientName);
ushort bitStored = dataset.GetSingleValue<ushort>(DicomTag.BitsStored);
ushort samplesPerPixel = dataset.GetSingleValue<ushort>(DicomTag.SamplesPerPixel);
ushort width = dataset.GetSingleValue<ushort>(DicomTag.Columns);
ushort height = dataset.GetSingleValue<ushort>(DicomTag.Rows);
DicomPixelData pixelData = DicomPixelData.Create(dataset);
for (int frame = 0; frame < pixelData.NumberOfFrames; frame++)
{
Bitmap gdiImg = new Bitmap(width, height);
IByteBuffer frameDataBuffer = pixelData.GetFrame(frame);
if (bitStored > 8)
{
ushort[] frameData = new ushort[width * height];
Buffer.BlockCopy(frameDataBuffer.Data, 0, frameData, 0, frameDataBuffer.Data.Length);
ushort maxVal = frameData.Max();
ushort minVal = frameData.Min();
double compressFactor = byte.MaxValue / (double)(maxVal - minVal) - 0.00000000001;
if (samplesPerPixel == 1) // Gray
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
double gray = frameData[i * width + j];
int grayGDI = (int)(gray * compressFactor);
grayGDI = grayGDI < 0 ? 0 : (grayGDI > 255 ? 255 : grayGDI);
Color color = Color.FromArgb(grayGDI, grayGDI, grayGDI);
gdiImg.SetPixel(j, i, color);
}
}
}
else if (samplesPerPixel == 3) // RGB
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int index = (i * width + j) * 3;
ushort r = frameData[index];
ushort g = frameData[index + 1];
ushort b = frameData[index + 2];
int rGDI = (int)(r * compressFactor);
int gGDI = (int)(g * compressFactor);
int bGDI = (int)(b * compressFactor);
rGDI = rGDI < 0 ? 0 : (rGDI > 255 ? 255 : rGDI);
gGDI = gGDI < 0 ? 0 : (gGDI > 255 ? 255 : gGDI);
bGDI = bGDI < 0 ? 0 : (bGDI > 255 ? 255 : bGDI);
Color color = Color.FromArgb(rGDI, gGDI, bGDI);
gdiImg.SetPixel(j, i, color);
}
}
}
}
else
{
byte[] frameData = frameDataBuffer.Data;
if (samplesPerPixel == 1) // Gray
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
byte gray = frameData[i * width + j];
Color color = Color.FromArgb(gray, gray, gray);
gdiImg.SetPixel(j, i, color);
}
}
}
else if (samplesPerPixel == 3) // RGB
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int index = (i * width + j) * 3;
byte r = frameData[index];
byte g = frameData[index + 1];
byte b = frameData[index + 2];
Color color = Color.FromArgb(r, g, b);
gdiImg.SetPixel(j, i, color);
}
}
}
}
string bmpOutputPath = Path.Combine(bmpOutputFolder, $"{frame + 1}.bmp");
gdiImg.Save(bmpOutputPath, ImageFormat.Bmp);
gdiImg.Dispose();
}
Console.WriteLine("所有帧图像已保存到 " + bmpOutputFolder);
}