internal static extern IntPtr CreateDIBSection( IntPtr hdc, ref NativeStructs.BITMAPINFO pbmi, uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
/// <summary> /// Allocates a bitmap of the given height and width. Pixel data may be read/written directly, /// and it may be drawn to the screen using PdnGraphics.DrawBitmap(). /// </summary> /// <param name="width">The width of the bitmap to allocate.</param> /// <param name="height">The height of the bitmap to allocate.</param> /// <param name="handle">Receives a handle to the bitmap.</param> /// <returns>A pointer to the bitmap's pixel data.</returns> /// <remarks> /// The following invariants may be useful for implementors: /// * The bitmap is always 32-bits per pixel, BGRA. /// * Stride for the bitmap is always width * 4. /// * The upper-left pixel of the bitmap (0,0) is located at the first memory location pointed to by the returned pointer. /// * The bitmap is top-down ("memory correct" ordering). /// * The 'handle' may be any type of data you want, but must be unique for the lifetime of the bitmap, and must not be IntPtr.Zero. /// * The handle's value must be understanded by PdnGraphics.DrawBitmap(). /// * The bitmap is always modified by directly reading and writing to the memory pointed to by the return value. /// * PdnGraphics.DrawBitmap() must always render from this memory location (i.e. it must treat the memory as 'volatile') /// </remarks> public static IntPtr AllocateBitmap(int width, int height, out IntPtr handle) { NativeStructs.BITMAPINFO bmi = new NativeStructs.BITMAPINFO(); bmi.bmiHeader.biSize = (uint)sizeof(NativeStructs.BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = NativeConstants.BI_RGB; bmi.bmiHeader.biSizeImage = 0; bmi.bmiHeader.biXPelsPerMeter = 96; bmi.bmiHeader.biYPelsPerMeter = 96; bmi.bmiHeader.biClrUsed = 0; bmi.bmiHeader.biClrImportant = 0; IntPtr pvBits; IntPtr hBitmap = SafeNativeMethods.CreateDIBSection( IntPtr.Zero, ref bmi, NativeConstants.DIB_RGB_COLORS, out pvBits, IntPtr.Zero, 0); if (hBitmap == IntPtr.Zero) { throw new OutOfMemoryException("CreateDIBSection returned NULL (" + Marshal.GetLastWin32Error().ToString() + ") while attempting to allocate " + width + "x" + height + " bitmap"); } handle = hBitmap; long bytes = (long)width * (long)height * 4; if (bytes > 0) { GC.AddMemoryPressure(bytes); } return(pvBits); }