如何在 C# 中将 stdole.stdPicture 转换为 .net 图像?
我正在构建一个 Outlook 插件,其中我将所有 Exchange 用户从全局地址列表复制到本地联系人。
问题是我也想传输交换用户的图片,但是 exchUser.GetPicture()
返回一个 stdole.stdPicture 并且我还没有找到一个有效的解决方案来下载或将其转换为图像/ jpg/...
这里是从全局地址列表中获取交换用户的代码:
private void EnumerateGAL()
{
Outlook.AddressList gal = Application.Session.GetGlobalAddressList();
if (gal != null)
{
for (int i = 1; i <= gal.AddressEntries.Count - 1; i++)
{
Outlook.AddressEntry addrEntry = gal.AddressEntries[i];
Outlook.ExchangeUser exchUser = addrEntry.GetExchangeUser();
if (addrEntry.AddressEntryUserType == Outlook.OlAddressEntryUserType.olExchangeUserAddressEntry
&& exchUser.CompanyName == "")
{
CreateContact(exchUser);
//exchUser.GetPicture() returns stdole.stdPicture
}
}
}
return;
}
我找到的最接近的解决方案是 stdole.IPictureDisp 的转换,它返回一个位图,但 IPuctureDisp 和 stdPicture 与我在某处读到的不同。
public static System.Drawing.Image ConvertPicture(stdole.IPictureDisp image)
{
int type = image.Type;
if (type == 1)
{
IntPtr hPal = (IntPtr)image.hPal;
return Image.FromHbitmap((IntPtr)image.Handle, hPal);
}
return null;
}
最后我需要下载图片,因为我只能将图片上传到有路径的联系人。 那么,有没有办法下载 stdPicture 或将其转换为能够下载的呢?
Im building an Add-In for Outlook where I copy all exchange users from the global address list to the local contacts.
The problem is I want transfer the picture of the exchange user too, but exchUser.GetPicture()
returns a stdole.stdPicture and I have not yet found a working solution to download or convert it into an image/jpg/...
Here the code to get the exchange User from the global address list:
private void EnumerateGAL()
{
Outlook.AddressList gal = Application.Session.GetGlobalAddressList();
if (gal != null)
{
for (int i = 1; i <= gal.AddressEntries.Count - 1; i++)
{
Outlook.AddressEntry addrEntry = gal.AddressEntries[i];
Outlook.ExchangeUser exchUser = addrEntry.GetExchangeUser();
if (addrEntry.AddressEntryUserType == Outlook.OlAddressEntryUserType.olExchangeUserAddressEntry
&& exchUser.CompanyName == "")
{
CreateContact(exchUser);
//exchUser.GetPicture() returns stdole.stdPicture
}
}
}
return;
}
The closest solution I found, was a conversion of stdole.IPictureDisp which returns a bitmap but IPuctureDisp and stdPicture isn´t the same as I read somewhere.
public static System.Drawing.Image ConvertPicture(stdole.IPictureDisp image)
{
int type = image.Type;
if (type == 1)
{
IntPtr hPal = (IntPtr)image.hPal;
return Image.FromHbitmap((IntPtr)image.Handle, hPal);
}
return null;
}
In the end I need to download the picture because I can only upload a picture to a contact with a path.
So, is there a way to download a stdPicture or convert it to be able to download it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
完成工作有四种主要方法。
“传统”方法是使用
System.Windows.Forms.AxHost
类中的GetIPictureDispFromPicture
和GetPictureFromIPicture
方法。它们都是类的受保护成员,因此您不能在外部使用它们。因此,通常对 AxHost 类进行子类化并公开在内部调用基类受保护方法的公共方法。这种方法允许您双向转换:第二个选择是使用
OleLoadPicture
或OleCreatePictureIndirect
。这里有一篇关于该主题的旧支持文章。OleLoadPicture
创建一个新的图片对象并根据流的内容对其进行初始化。第三个选择是使用 VB6 兼容性库(此处记录)。要使用此功能,您需要添加对
Microsoft.VisualBasic.Compatibility.dll
的引用,该引用列在添加引用
对话框的 .NET 选项卡上(它驻留在 GAC 中)。然后,您可以使用Support
类中的ImageToIPictureDisp
和IPictureDispToImage
方法。这显然是迄今为止最简单的方法,尽管它确实引入了 VB6 兼容性 DLL。在内部,VB6 兼容性代码看起来很像上面的第二个选项 - 使用OleCreatePictureIndirect
。最后,您可以自己实现
IPictureDisp
和IPicture
。如果您只想从图像转换为IPictureDisp
,这很好,但不能帮助您向另一个方向进行转换。下面的实现依赖于 Image 实际上是派生的 Bitmap 类型,因为我们在内部调用了 Bitmap.GetHbitmap。如果您想保留对通用Image
类型的支持,则必须做更多的工作来 p/调用一堆未记录的 GDI 方法There are four main ways to get the job done.
The "traditional" approach is to use the
GetIPictureDispFromPicture
andGetPictureFromIPicture
methods in theSystem.Windows.Forms.AxHost
class. These are both protected members of the class, so you can't use them externally. For this reason, it is common to subclass theAxHost
class and expose public methods that internally call the base class protected methods. This approach allows you to convert in both directions:Your second option is to use
OleLoadPicture
orOleCreatePictureIndirect
. There's an old support article on the topic here.OleLoadPicture
creates a new picture object and initializes it from the contents of a stream.Your third option is to use the VB6 compatibility library, documented here. To use this, you'll need to add a reference to
Microsoft.VisualBasic.Compatibility.dll
, which is listed on the .NET tab of theAdd References
dialog (it resides in the GAC). Then, you can use theImageToIPictureDisp
andIPictureDispToImage
methods in theSupport
class. This is obviously by far the simplest approach, although it does pull in the VB6 compatibility DLL. Internally, the VB6 compatibility code looks a lot like the second option above – usingOleCreatePictureIndirect
.Finally, you can implement
IPictureDisp
andIPicture
yourself. This is fine if you just want to convert from an Image to anIPictureDisp
, but doesn't help you converting in the other direction. The implementation below relies on the Image actually being a derived Bitmap type, because we callBitmap.GetHbitmap
internally. If you want to keep the support to the genericImage
type, you'll have to do a lot more work to p/invoke to a bunch of undocumented GDI methods instead