Search code examples
c#bitmapsystem.drawingitk

Convert Simpleitk image into Bitmap. System.ArgumentException


I want to read a dicom image using simpleitk, convert it into a bitmap and then display the result in a pictureBox. But when I'm trying to do this, an ArgumentException is thrown. How can I solve this?

Here is my code:

OpenFileDialog dialog = new OpenFileDialog();
dialog.Title = "Open";
dialog.Filter = "DICOM Files (*.dcm;*.dic)|*.dcm;*.dic|All Files (*.*)|*.*";
dialog.ShowDialog();
if (dialog.FileName != "")
{
    using (sitk.ImageFileReader reader = new sitk.ImageFileReader())
    {
        reader.SetFileName(dialog.FileName);                   
        reader.SetOutputPixelType(sitk.PixelIDValueEnum.sitkFloat32);
        sitk.Image image = reader.Execute();

        var castedImage = sitk.SimpleITK.Cast(image, 
            sitk.PixelIDValueEnum.sitkFloat32);
        var size = castedImage.GetSize();
        int length = size.Aggregate(1, (current, i) => current * (int)i);
        IntPtr buffer = castedImage.GetBufferAsFloat();

        // Declare an array to hold the bytes of the bitmap.                    
        byte[] rgbValues = new byte[length];

        // Copy the RGB values into the array.
        Marshal.Copy(buffer, rgbValues, 0, length);

        Stream stream = new MemoryStream(rgbValues);

        Bitmap newBitmap = new Bitmap(stream);

        //I have tried in this way, but it generated ArgumentException too
        //Bitmap newBitmap = new Bitmap((int)image.GetWidth(), (int)image.GetHeight(), (int)image.GetDepth(), PixelFormat.Format8bppIndexed, buffer);

        Obraz.pic.Image = newBitmap;
    }
}

Solution

  • Thank you for your comments and attempts to help. After consultations and my own searching on the internet I solved this issue. The first problem was the inadequate representation of pixel image. I had to change Float32 to UInt8 to provide an eight-bit for pixel.

    var castedImage = sitk.SimpleITK.Cast(image2, sitk.PixelIDValueEnum.sitkUInt8);
    

    Then I would already create a Bitmap using the constructor that was was commented out in question, but with (int)image.GetWidth() instead of (int)image.GetDepth().

    Bitmap newBitmap = new Bitmap((int)image.GetWidth(), (int)image.GetHeight(), (int)image.GetWidth(), PixelFormat.Format8bppIndexed, buffer);
    

    Unfortunately, a new problem appeared. The image, that was supposed to be in gray scale, was displayed in strange colors. But I found the solution here

    ColorPalette pal = newBitmap.Palette;
                    for (int i = 0; i <= 255; i++)
                    {
                        // create greyscale color table
                        pal.Entries[i] = Color.FromArgb(i, i, i);
                    }
                    newBitmap.Palette = pal; // you need to re-set this property to force the new ColorPalette