As I wrote my few last posts about how to access the BitmapSource WIC image pixels, I have found a post in the MSDN forum, which exposes a static class called Imaging. This amazing class which somehow was very hard to find, can do a great work with image-interop. Looking inside the MSDN for the Imaging class, I found the following methods:
The CreateBitmapSourceFromMemorySection is the best match for creating a BitmapSource from a memory section. Looking further inside the updated MSDN it said that "CreateBitmapSourceFromMemorySection - Returns a managed BitmapSource, based on the provided unmanaged memory location".
When I tried to pass an address of a memory, allocated by the Marshal.AllocHGlobal method, to the CreateBitmapSourceFromMemorySection method, it threw a COM exception!
Digging inside this method using Reflector, it seems that it calls the WICCreateBitmapFromSection, which is a WIC unmanaged function defined in the windowscodecs.dll (The MSDN didn't give any clue of what happened, or how to use this function!).
So I turned to the MSDN post again. It figured out that this method must be used with a file-mapping (too weird).
The code snippet bellow demonstrates the use of this method:
// Create a new file mapping object to back the bitmap
IntPtr section = CreateFileMapping(
INVALID_HANDLE_VALUE,
IntPtr.Zero,
PAGE_READWRITE,
0,
numBytes,
null);
IntPtr pixels = MapViewOfFile(
section,
FILE_MAP_ALL_ACCESS,
0,
0,
numBytes);// Manipulate the pixels using the pixels pointer
// Create a bitmap source using the memory section
BitmapSource source = Imaging.CreateBitmapSourceFromMemorySection(
section,
_pixelWidth,
_pixelHeight,
_pixelFormat,
_stride,
0);
What does this method do?
This method encapsulates the memory provided by the section-pointer with a WPF BitmapSource instance. Now we can set this BitmapSource instance as a source of an Image.
Disadvantages:
There is no option to manipulate the pixels and reuse the same BitmapSource (calling the Image.InvalidateVisual method is not working). The only way is to call the CreateBitmapSourceFromMemorySection again (this creates a new BitmapSource), and set the Image.Source property again). Since the BitmapSource only encapsulates this memory, no copy is made, but a new managed instance of a BitmapSource is still created in the managed heap. If we use this method to display a series of images (such as the Video solution), we causes the CPU and the garbage collector to work, and the Virtual Memory/Page Faults to increase (and decrease after a while of course).
Comparing this solution to my previous unofficial one: The unofficial solution performs a little better, but at the same time presents a versioning risk.
Download the code from here.