I am trying to transform a bitmap object into a DicomFile object with version 3.0.2.0 of fo-dicom (which I got through NuGet). However, when I run the code below (which I found here), I don't even get past properly initializing the DicomDataset.
using Dicom;
using Dicom.Imaging;
using Dicom.IO.Buffer;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text;
namespace DICOM
{
class BitmapToDICOM
{
public static DicomFile TransformBitmapToDICOM(Bitmap bitmap)
{
bitmap = GetValidImage(bitmap);
int rows, columns;
byte[] pixels = GetPixels(bitmap, out rows, out columns);
MemoryByteBuffer buffer = new MemoryByteBuffer(pixels);
DicomDataset dataset = new DicomDataset();
dataset.Add(DicomTag.BitsAllocated, (ushort)8);
// Prepare the dataset
FillDataset(dataset);
dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value);
dataset.Add(DicomTag.Rows, (ushort)rows);
dataset.Add(DicomTag.Columns, (ushort)columns);
DicomPixelData pixelData = DicomPixelData.Create(dataset, true);
pixelData.BitsStored = 8;
pixelData.BitsAllocated = 8;
pixelData.SamplesPerPixel = 3;
pixelData.HighBit = 7;
pixelData.PixelRepresentation = 0;
pixelData.PlanarConfiguration = 0;
pixelData.AddFrame(buffer);
return new DicomFile(dataset);
}
private static void FillDataset(DicomDataset dataset)
{
//type 1 attributes.
dataset.Add(DicomTag.SOPClassUID, DicomUID.SecondaryCaptureImageStorage);
dataset.Add(DicomTag.StudyInstanceUID, GenerateUid());
dataset.Add(DicomTag.SeriesInstanceUID, GenerateUid());
dataset.Add(DicomTag.SOPInstanceUID, GenerateUid());
//type 2 attributes
dataset.Add(DicomTag.PatientID, "12345");
dataset.Add(DicomTag.PatientName, string.Empty);
dataset.Add(DicomTag.PatientBirthDate, "00000000");
dataset.Add(DicomTag.PatientSex, "M");
dataset.Add(DicomTag.StudyDate, DateTime.Now);
dataset.Add(DicomTag.StudyTime, DateTime.Now);
dataset.Add(DicomTag.AccessionNumber, string.Empty);
dataset.Add(DicomTag.ReferringPhysicianName, string.Empty);
dataset.Add(DicomTag.StudyID, "1");
dataset.Add(DicomTag.SeriesNumber, "1");
dataset.Add(DicomTag.ModalitiesInStudy, "CR");
dataset.Add(DicomTag.Modality, "CR");
dataset.Add(DicomTag.NumberOfStudyRelatedInstances, "1");
dataset.Add(DicomTag.NumberOfStudyRelatedSeries, "1");
dataset.Add(DicomTag.NumberOfSeriesRelatedInstances, "1");
dataset.Add(DicomTag.PatientOrientation, "F/A");
dataset.Add(DicomTag.ImageLaterality, "U");
}
private static DicomUID GenerateUid()
{
StringBuilder uid = new StringBuilder();
uid.Append("1.08.1982.10121984.2.0.07").Append('.').Append(DateTime.UtcNow.Ticks);
return new DicomUID(uid.ToString(), "SOP Instance UID", DicomUidType.SOPInstance);
}
private static Bitmap GetValidImage(Bitmap bitmap)
{
if (bitmap.PixelFormat != PixelFormat.Format24bppRgb)
{
Bitmap old = bitmap;
using (old)
{
bitmap = new Bitmap(old.Width, old.Height, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawImage(old, 0, 0, old.Width, old.Height);
}
}
}
return bitmap;
}
private static byte[] GetPixels(Bitmap image, out int rows, out int columns)
{
rows = image.Height;
columns = image.Width;
if (rows % 2 != 0 && columns % 2 != 0)
--columns;
BitmapData data = image.LockBits(new Rectangle(0, 0, columns, rows), ImageLockMode.ReadOnly, image.PixelFormat);
IntPtr bmpData = data.Scan0;
try
{
int stride = columns * 3;
int size = rows * stride;
byte[] pixelData = new byte[size];
for (int i = 0; i < rows; ++i)
Marshal.Copy(new IntPtr(bmpData.ToInt64() + i * data.Stride), pixelData, i * stride, stride);
//swap BGR to RGB
SwapRedBlue(pixelData);
return pixelData;
}
finally
{
image.UnlockBits(data);
}
}
private static void SwapRedBlue(byte[] pixels)
{
for (int i = 0; i < pixels.Length; i += 3)
{
byte temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
}
}
}
When it reaches the "dataset.Add(DicomTag.StudyInstanceUID, GenerateUid());" part of the code I get a "System.TypeInitializationException" with a full stack trace of
System.TypeInitializationException occurred
HResult=0x80131534
Message=Typeinitialiseringsfunktionen for 'Dicom.DicomEncoding' triggered an exception.
Source=Dicom.Core
StackTrace:
at Dicom.DicomMultiStringElement..ctor(DicomTag tag, String[] values)
at Dicom.DicomUniqueIdentifier..ctor(DicomTag tag, DicomUID[] values)
at Dicom.DicomDataset.DoAdd[T](DicomVR vr, DicomTag tag, IList`1 values, Boolean allowUpdate)
at Dicom.DicomDataset.DoAdd[T](DicomTag tag, IList`1 values, Boolean allowUpdate)
at Dicom.DicomDataset.Add[T](DicomTag tag, T[] values)
at DICOM.BitmapToDICOM.FillDataset(DicomDataset dataset) in [...]\Documents\Visual Studio 2015\Projects\DICOM\DICOM\BitmapToDICOM.cs:line 44
at DICOM.BitmapToDICOM.TransformBitmapToDICOM(Bitmap bitmap) in [...]\Documents\Visual Studio 2015\Projects\DICOM\DICOM\BitmapToDICOM.cs:line 25
at DICOM.Program.Main(String[] args) in [...]\Documents\Visual Studio 2015\Projects\DICOM\DICOM\Program.cs:line 18
Inner Exception 1:
NullReferenceException: The object reference is not set to an instance of an object.
What am I doing wrong?
If there are better ways of turning a bitmap into a DicomFile in fo-dicom I am all ears.
User contributions licensed under CC BY-SA 3.0