byte array to BitmapImage

3,282 views
Skip to first unread message

Robin VASSEUR

unread,
Jan 29, 2016, 1:03:20 AM1/29/16
to Fellow Oak DICOM
Hi,

I'm training to use FO-DICOM, here is what I did :

DicomImage image = new DicomImage(filename);
byte[] byteArray = image.PixelData.GetFrame(0).Data;

Here are some of my image datas:

PhotometricInterpretation=MONOCHROME2
SamplePerPixel=1
BitsAllocated=16
BitsStored=12
HighBit=11
PixelRepresentation=0
NumberOfFrames=0

so the length of my byteArray is 524288, which seems to be good.

Now, (again, this is for training purpose, I know there are other ways to do it), I want to convert this byteArrays into a BitmapImage, or WritableImage, or whatever I could display on my WPF project using a Image.

I've been trying two methods:

- A "classic" way I found everywhere on internet:

                BitmapImage bitmapImage;
                using (MemoryStream ms = new MemoryStream(byteArray))
                {
                    bitmapImage = new BitmapImage();
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = ms;
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();   // Here i get an exception
                    bitmapImage.Freeze();
                }

with this I get a "System.NotSupportedException" 

"Une exception non gérée du type 'System.NotSupportedException' s'est produite dans PresentationCore.dll
Informations supplémentaires : Impossible de trouver un composant d'image adapté pour terminer"

I guess in english it's something like : "Can't find a suitable image component to complete"

I guess this is not really a fo-ficom related question, but I hoped someone could tell me if i'm just using the "PixelData" the wrong way or something else...

- The second method was :

                var width = 512;
               
var height = 512;
               
var dpiX = 96d;
               
var dpiY = 96d;
               
var pixelFormat = PixelFormats.Gray16;
               
var bytesPerPixel = 2;
               
var stride = bytesPerPixel * width;


               
var wbm = BitmapSource.Create(width, height, dpiX, dpiY, pixelFormat, null, tmp, stride);


This way, it's almost working ! The problem is that it's taking the image as a MONOCHROME1, and not as a MONOCHROME2 (I mean black & white are reverse), I don't really know how to fix this

Anders Gustafsson Cureos AB

unread,
Jan 29, 2016, 1:36:01 AM1/29/16
to Fellow Oak DICOM
Hi Robin,

I don't think you need to go through all the hassle you are describing just to create a BitmapImage. I suggest you take a look at the Image rendering page on the wiki.

In short, fo-dicom for .NET is default configured to System.Drawing and Bitmap imaging. To switch to WPF and WriteableBitmap/ImageSource imaging, you first need to re-configure the image manager (also see here):

ImageManager.SetImplementation(WPFImageManager.Instance);

Then, you can cast the result of the RenderImage operation to a WriteableBitmap (which is derived from ImageSource and BitmapSource) like either of these:

WriteableBitmap wbm = image.RenderImage().As<WriteableBitmap>();
WriteableBitmap wbm = image.RenderImage().AsWriteableBitmap();

If you are using the .As<> "cast operator" you can even cast to ImageSource or BitmapSource directly.

Regards,
Anders @ Cureos

Robin VASSEUR

unread,
Jan 29, 2016, 2:00:50 AM1/29/16
to Fellow Oak DICOM
Hi, thank you for your answer!

I've been able to render images with these methods. What I want is being able to modify the image, that's why I want to go though the byte array stuff.

My goal is to merge multiple slices into one, by taking a few pixels from each slice and putting them into one byte array. 

May be there are other ways to do that, but I think the Image rendering part can't handle that right?

Thank you,

Robin

Anders Gustafsson Cureos AB

unread,
Jan 29, 2016, 2:09:38 AM1/29/16
to Fellow Oak DICOM
Hi again Robin,

That's right, there is no support for more advanced image processing in fo-dicom itself. I suggest you take a look at a helper package like WriteableBitmapEx for merging etc. images.

Regards,
Anders

Robin VASSEUR

unread,
Feb 5, 2016, 5:21:59 AM2/5/16
to Fellow Oak DICOM
Hi,

I just made it work, and that is exactly what I needed, thank you so much :)

Regards,
Robin

Robin VASSEUR

unread,
Feb 15, 2016, 5:17:03 AM2/15/16
to Fellow Oak DICOM
Hello,

Your answer helped me a lot, but now for another problem I would really like do understand why the example I gave did not work.

It seems like when I do :

byte[] byteArray = image.PixelData.GetFrame(0).Data;

It does not give a "valid" byte array. For a simpler example :

MemoryStream ms = new MemoryStream(byteArray);
Image i = Image.FromStream(ms);                   // This line give a 'System.ArgumentException' and just say the argument is invalid
i
.Save("test.bmp", ImageFormat.Bmp);

Why? Could it be from an endianness problem? How could I fix it?

Anders Gustafsson Cureos AB

unread,
Feb 15, 2016, 9:00:06 AM2/15/16
to Fellow Oak DICOM
Robin,

the stream you get from the pixel data byte array is not a bitmap image, and therefore you end up with an ArgumentException. If you want to create a new image for processing, based on the original pixel data (frame), I recommend you try something like this instead:

var i = new Bitmap(image.RenderImage(0).AsBitmap());

Hope this helps!

Regards,
Anders @ Cureos
Reply all
Reply to author
Forward
0 new messages