Используйте для этого следующие функции:
private const string Gdi32Dll = @".\gdi32.dll";
[DllImport(Gdi32Dll, ExactSpelling = true)]
internal static extern int SetDIBitsToDevice(
IntPtr hdc,
int xdst,
int ydst,
int width,
int height,
int xsrc,
int ysrc,
int start,
int lines,
IntPtr bitsptr,
IntPtr bmiptr,
int color);
public static Bitmap BitmapFromDIB(IntPtr dibPtrArg)
{
Bitmapinfoheader bmiHeader;
IntPtr pixptr = IntPtr.Zero;
GetPixelInfo(dibPtrArg, out pixptr, out bmiHeader);
Bitmap bitMap = new Bitmap(bmiHeader.biWidth, bmiHeader.biHeight);
Graphics scannedImageGraphics = Graphics.FromImage(bitMap);
IntPtr hdc = scannedImageGraphics.GetHdc();
SetDIBitsToDevice(
hdc,
0, // XDest
0, // YDest
bmiHeader.biWidth,
bmiHeader.biHeight,
0, // XSrc
0, // YSrc
0, // uStartScan
bmiHeader.biHeight, // cScanLines
pixptr, // lpvBits
dibPtrArg, // lpbmi
DibRgbColors); // 0 = literal RGB values rather than palette
scannedImageGraphics.ReleaseHdc(hdc);
return bitMap;
}
private static void GetPixelInfo(IntPtr bmpptr, out IntPtr pix, out Bitmapinfoheader bmi)
{
bmi = new Bitmapinfoheader();
Marshal.PtrToStructure(bmpptr, bmi); // copy into struct.
if (bmi.biSizeImage == 0)
{
bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight;
}
int p = bmi.biClrUsed;
if ((p == 0) && (bmi.biBitCount <= 8))
{
p = 1 << bmi.biBitCount;
}
pix = (IntPtr)((p * 2) + bmi.biSize + (int)bmpptr);
}