.NET中操作IPicture、IPictureDisp的小随笔

 

【题外话】

最近在做一个调用某实验仪器的程序,这个仪器提供了Windows上COM的接口。调用仪器的时候需要传输图片,提供的接口里使用了IPicture这个接口,由于以前没接触过,所以查找了一些资料,整理了一下与.NET中System.Drawing.Image的互转的方式。

【文章索引】

  1. IPicture和IPictureDisp是什么
  2. 使用AxHost实现与System.Drawing.Image的互转
  3. 使用VB6 compatibility library实现互转
  4. Alpha通道的问题

【一、IPicture和IPictureDisp是什么】

根据MSDN上对IPicture和IPictureDisp的说明来看,IPicture与IPictureDisp提供了与语言无关的接口,这个接口用来提供对位图(Bitmap)、图标(Icon)、图元文件(Metafile)的抽象,其中后者还实现了IDispatch接口以实现COM的自动化接口。总之,如果通过COM接口传输图像的话,可能会接触到这两个接口。

【二、使用AxHost实现与System.Drawing.Image的互转】

.NET在System.Windows.Forms下提供了一个叫AxHost的类来实现与ActiveX控件进行访问,不过这里用到的只是在AxHost里的protected的静态方法而已。由于是protected的方法,所以没有办法直接调用,好在AxHost不是密封的类,所以我们还可以通过集成AxHost来实现调用,例如以下的代码:

 1 using System.Drawing;
2 using System.Windows.Forms;
3
4 public sealed class IPictureConverter : AxHost
5 {
6 private IPictureConverter() : base("") { }
7
8 #region IPictureDisp
9 public static stdole.IPictureDisp ImageToIPictureDisp(Image image)
10 {
11 return (stdole.IPictureDisp)GetIPictureDispFromPicture(image);
12 }
13
14 public static Image IPictureDispToImage(stdole.IPictureDisp pictureDisp)
15 {
16 return GetPictureFromIPictureDisp(pictureDisp);
17 }
18 #endregion
19
20 #region IPicture
21 public static stdole.IPicture ImageToIPicture(Image image)
22 {
23 return (stdole.IPicture)GetIPictureFromPicture(image);
24 }
25
26 public static Image IPictureToImage(stdole.IPicture picture)
27 {
28 return GetPictureFromIPicture(picture);
29 }
30 #endregion
31 }

【三、使用VB6 compatibility library实现互转】

除了AxHost,其实微软也提供了另外一个库提供托管的Image与IPicture等互转,那就是Microsoft.VisualBasic.Compatibility.dll,其中有一个叫Support的类提供了很多向后兼容的方法。对于IPicture或IPictureDisp的转换,我们可以写如下代码:

 1 using System.Drawing;
2 using Microsoft.VisualBasic.Compatibility.VB6;
3
4 public static class IPictureConverter
5 {
6 #region IPictureDisp
7 public static stdole.IPictureDisp ImageToIPictureDisp(Image image)
8 {
9 return (stdole.IPictureDisp)Support.ImageToIPictureDisp(image);
10 }
11
12 public static Image IPictureDispToImage(stdole.IPictureDisp pictureDisp)
13 {
14 return Support.IPictureDispToImage(pictureDisp);
15 }
16 #endregion
17
18 #region IPicture
19 public static stdole.IPicture ImageToIPicture(Image image)
20 {
21 return (stdole.IPicture)Support.ImageToIPicture(image);
22 }
23
24 public static Image IPictureToImage(stdole.IPicture picture)
25 {
26 return Support.IPictureToImage(picture);
27 }
28 #endregion
29 }

仔细看其实与上一段代码非常类似,本着好奇的态度,我们Relector一下这些方法实现的代码。

看起来两者几乎是一样的,不过有意思的是,虽然两者的很多方法如GetPICTDESCFromPicture等都不是同一个方法,甚至IPicture等接口都不是在一个库里定义的(AxHost是在System.Windows.Forms.UnsafeNativeMethods中定义的,而VB6 compatibility library则是在单独的一个stdole.dll中定义的),但是其调用的方法里执行的内容基本都相同,IPicture等接口也都是ComImport的同一个Guid,而两个方法实现的源头,更都是DllImport的oleaut32.dll,调用其中的“OleCreatePictureIndirect”方法,所以上述两种方法是完全一样的。

不过在4.0的CLR下,提供的Microsoft.VisualBasic.Compatibility.dll的版本为10.0.0.0,Support类以及相应的方法都被标记为过时的(Obsolete),所以编译的时候提示的警告也蛮让人恶心的(2.0的CLR下提供的8.0.0.0的dll没有这个问题),所以倒不妨采用第一种方法。

【四、Alpha通道的问题】

如果你的图片包含Alpha通道的话,上述转换可能会导致颜色有些问题,由于IPicture没有办法支持Alpha通道,所以妥协的办法只能是要么不用Alpha通道,要么在转换为IPicture前在图片底下垫上一个纯色的背景(比如对方程序中要显示图片的位置的背景),比如How to Convert a System.Drawing.Image to an IPictureDisp with Alpha Transparency这篇文章就是这么做的。

【相关链接】

  1. IPicture interface:http://msdn.microsoft.com/en-us/library/ms680761.aspx
  2. IPictureDisp interface:http://msdn.microsoft.com/en-us/library/ms680762.aspx
  3. Converting between IPictureDisp and System.Drawing.Image:http://blogs.msdn.com/b/andreww/archive/2007/07/30/converting-between-ipicturedisp-and-system-drawing-image.aspx

如果您觉得本文对您有所帮助,不妨点击下方的“推荐”按钮来支持我!

如果您想转载文本,请您务必注明文章的作者和出处链接,谢谢合作!

 
分类: C#

.NET中操作IPicture、IPictureDisp的更多相关文章

  1. .NET中操作IPicture、IPictureDisp的小随笔

    [题外话] 最近在做一个调用某实验仪器的程序,这个仪器提供了Windows上COM的接口.调用仪器的时候需要传输图片,提供的接口里使用了IPicture这个接口,由于以前没接触过,所以查找了一些资料, ...

  2. Python中操作mysql的pymysql模块详解

    Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...

  3. JQuery中操作Css样式的方法

    JQuery中操作Css样式的方法//1.获取和设置样式 $("#tow").attr("class")获取ID为tow的class属性 $("#tw ...

  4. C#中操作Word(1)—— word对象模型介绍

    一.开发环境布置 C#中添加对Word的支持,只需添加对Microsoft.Office.Interop.Word的命名空间,如下图所示,右键点击“引用”,在弹出的“添加引用”对话框中选中COM标签页 ...

  5. VC++中操作XML(MFC、SDK)转

    [转]VC++中操作XML(MFC.SDK) XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++ ...

  6. VBA中操作XML

    OFFICE2007之后使用了OpenXml标准(伟大的改变),定制文本级的Ribbon可以通过修改压缩包内的xml文件来实现. 先学习一下VBA中操作XML的方法 先引用Microsoft XML ...

  7. VC线程中操作控件,引起程序卡死的问题。

    [问题还原] 线程中操作控件,具体为控制一个按键的使能,使能后结束线程. 主程序中有一个死循环,等待线程结束. 然后,就没有然后了-- [解决方案] 在主程序死循环中,如果检测到界面消息,优先处理掉.

  8. c#中操作word文档-四、对象模型

    转自:http://blog.csdn.net/ruby97/article/details/7406806 Word对象模型  (.Net Perspective) 本文主要针对在Visual St ...

  9. C#中操作WMI的类库-实现远程登录共享

    WMI是Windows Management Instrumentation的简称,即:视窗管理规范.在Windows 2000或以后的版本中均安装得有,NT4.0则需要安装WMI的核心组件.通过WM ...

随机推荐

  1. 《STL源代码分析》---stl_list.h读书笔记

    STL在列表list它是一种经常使用的容器.list不连续双向链表在内存,而且是环形. 理解列表如何操作的详细信息,然后.阅读STL名单上的代码是最好的方法. G++ 2.91.57.cygnus\c ...

  2. uva10827-Maximum sum on a torus(矩阵最大和的变形)

    题目;uva10827-Maximum sum on a torus(矩阵最大和的变形) 题目大意:就是uva108的变形,矩阵能够连通,就是能够从后面连到前面.这里把矩阵复制三遍,然后又一次生成一个 ...

  3. 【高德地图API】从零开始学高德JS API(七)——定位方式大揭秘

    原文:[高德地图API]从零开始学高德JS API(七)——定位方式大揭秘 摘要:关于定位,分为GPS定位和网络定位2种.GPS定位,精度较高,可达到10米,但室内不可用,且超级费电.网络定位,分为w ...

  4. SVN & Git (二)

    Git:是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.Git 是 Linus T ...

  5. Unix命令操作

    基本命令 [ man 查看 ]--万能命令 1.ls 列出文件 (-al) 2.cd 转换目录 3.mkdir 建立新目录 4.cp 拷贝文件 (-R) 5.rm 删除文件 (-rf) 6.mv 移动 ...

  6. JAVA简单Swing图形界面应用演示样例

    JAVA简单Swing图形界面应用演示样例 package org.rui.hello; import javax.swing.JFrame; /** * 简单的swing窗体 * @author l ...

  7. Yii Framework2.0开发教程(10)配合mysql数据库实现用户登录

    1.首先在mysql创建一个存用户的表格 create table test_user ( user_id bigint(20) unsigned not null auto_increment co ...

  8. NotePad++ for PHP

    原文:NotePad++ for PHP 一.安装设置 1.首先根据你的系统下载相应的安装文件.http://notepad-plus-plus.org/ Notepad++插件:http://sou ...

  9. js 正则之检测素数

    原文:js 正则之检测素数 相信很多人应该看过这篇文章,我第一次看到的时候是11年的样子,那时候学vbs的时候看过这个问题.原文<检查素数的正则表达式>,在文章里已经解释了他是怎么判断的, ...

  10. 蓝色的成长记录——追逐DBA(8):为了夺回SP报告,回顾oracle的STATSPACK实验

    ***********************************************声明*************************************************** ...