views:

236

answers:

4

I need to write an app to playback a DICOM multiframe image. Each frame is stored in JPEG format. All the frames are stored consecutively in one file. Right now, I read out each frame data and pass it to the following routine to construct a Bitmap for display:

    Bitmap CreateBitmap(byte[] pixelBuffer, int frameSize)
    {
        Bitmap image = null;

        try
        {
            long startTicks = DateTime.Now.Ticks;
            MemoryStream pixelStream = new MemoryStream(pixelBuffer, 0, frameSize);
            image = new Bitmap(pixelStream);
            loadTime = DateTime.Now.Ticks - startTicks;
        }
        catch (Exception ex)
        {
            Log.LogException(ex);
        }

        return image;
    }

During the test, everything works fine except that the performance in the above routine is not optimal. For the 800x600 frame size, the time it takes in this routine is either 0msec and 15msec (I don't know why). For the 1024x768 frame size, the time it takes is either 15msec or 31msec. My goal is to stream the image data in and playback the image (1024x768 version) in 60Hz without dropping a frame. That suggests I have to decompress the JPEG frame within 15msec constantly. So my question is what's the better way to do this?

+5  A: 

It's 0 msec or 15 msec because your timer lacks resolution. Use QueryPerformanceCounter to get accurate times.

The WPF JPEG decoder (System.Windows.Media.Imaging) is faster than the GDI+ decoder.

Frank Krueger
Thanks! Could you give me an example of how to draw the BitmapFrame returned by the JpegBitmapDecoder? I can't use Graphics.DrawImage() in OnPaint() anymore.
JohnY
Drawing a WPF image using GDI+ will be a pain. If you have to render to WinForms, then stick with the GDI+ classes.
Frank Krueger
+2  A: 

I realize you probably have constraints that dictate the JPEG-frame requirement, but the best way to do this is to use a different format designed for video, like MEPG or Quicktime. Translate your JPEG frames into a video format designed for streaming and stream that, instead.

Randolpho
A: 

You could try WIC, the windows imaging component. This is probably used behind the scenes by WPF, suggested in another answer.

Bruno Martinez
+1  A: 

Ok, I figured out how to use System.Windows.Media.Imaging.JpegBitmapEncoder in the method now:

            JpegBitmapDecoder decoder = new JpegBitmapDecoder(pixelStream, BitmapCreateOptions.None, BitmapCacheOption.None);
            BitmapFrame frame = decoder.Frames[0];
            frame.CopyPixels(pixelBuffer, stride, 0);

I measured the performance and it seems to have 100% improvement. Nice job from WIC and WPF. Decoding 1024x768 image is down to 9 to 10 msec now.

JohnY