一、Dib to Bitmap doesn't work in WPF
代码如下:
protected byte[] BitmapFromDIB(IntPtr pDIB, IntPtr pPix)
{
MethodInfo mi = typeof(Bitmap).GetMethod("FromGDIplus", BindingFlags.Static | BindingFlags.NonPublic);
if (mi == null)
return null;
IntPtr pBmp = IntPtr.Zero;
int status = GdipCreateBitmapFromGdiDib(pDIB, pPix, ref pBmp);
if ((status == 0) && (pBmp != IntPtr.Zero))
{
Bitmap bmtemp = (Bitmap)mi.Invoke(null, new object[] { pBmp });
byte[] byres = null;
if (bmi.biBitCount == 1)
{
ImageConverter ic = new ImageConverter();
byres = ic.ConvertTo(bmtemp, typeof(byte[])) as byte[];
}
else
{
MemoryStream ms = new MemoryStream();
bmtemp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byres = ms.ToArray();
}
return byres;
}
else
return null;
}
关于这个问题,不管是在国外还是国内的博客网站上,好多人都遇到这样的问题,我在最近的公司的项目中,在使用松下的一款扫描仪时,遇到了同样的问题,在WPF中使用此方法时,返回的状态码为18,根据msdn的API解释18为GdiplusNotInitialized,即GDI+未被初始化,关于状态码的枚举如下:
typedef enum {
Ok = 0,
GenericError = 1,
InvalidParameter = 2,
OutOfMemory = 3,
ObjectBusy = 4,
InsufficientBuffer = 5,
NotImplemented = 6,
Win32Error = 7,
WrongState = 8,
Aborted = 9,
FileNotFound = 10,
ValueOverflow = 11,
AccessDenied = 12,
UnknownImageFormat = 13,
FontFamilyNotFound = 14,
FontStyleNotFound = 15,
NotTrueTypeFont = 16,
UnsupportedGdiplusVersion = 17,
GdiplusNotInitialized = 18,
PropertyNotFound = 19,
PropertyNotSupported = 20,
ProfileNotFound = 21
} Status;
详细可以查看此地址:https://msdn.microsoft.com/en-us/library/ms534175.aspx 里面有更为详尽的说明。
看到这里,稍微了解点WPF和WinForm底层的人就会知道为什么在WPF中会出现这样的问题,WPF的底层是基于DirectX的,而WinForm是基于GDI+的,两者有着本质的区别,所以在WPF中才会报出未初始化Gdiplus的问题,在msdn的API中,已经提供了解决方案,如何初始化GDI+,以及如何关闭GDI+,地址:https://msdn.microsoft.com/en-us/library/ms534077.aspx msdn中提供了C++的示例,对于我这种小白来说,不知道该咋在C#里面调用。
于是另辟蹊经,新建了一个与项目无关的WinForm项目,在WPF项目中添加引用,在扫描前初始化WinForm项目中的一个窗体,它实际是只起了一个初始化Gdiplus的作用,但这却解决了我的问题,达到了事半功倍的效果。
二、小结
开发过程中,或许我们会遇到各种各样的问题,当然大多数的问题,前人已经解决的差不多了,但是不一定会适合我们,在时间不允许的情况下,我们不妨去选择自己最熟悉的,最直接的解决方案。适合自己的才是最好的!