cwbboy
制定计划,然后努力
http://www.giwi.cn
广州知微科技,广州市知微科技有限公司,微软合作伙伴,软件解决方案,电信解决方案,开发,广州移动ADC,广东电信商务领航,CSF ,Connect Service Framwork
在.net 中调用win32API :GetBitmapBits ,获取位图的颜色数组,发送给打印机。
这段时间处理打印问题,需要得到一个黑白的位图文件的颜色信息。 目前只发现使用Win32的API:
GetBitmapBits
函数可以实现。但经过N次的试验后,总是失败。
Win32 API GetBitmapBits函数的定义:
GetBitmapBits
The GetBitmapBits function copies the bitmap bits of a specified device
-
dependent bitmap into a buffer.
Note This function
is
provided only
for
compatibility with
16
-
bit versions of Windows. Applications should use the GetDIBits function.
LONG GetBitmapBits(
HBITMAP hbmp,
//
handle to bitmap
LONG cbBuffer,
//
number of bytes to copy
LPVOID lpvBits
//
buffer to receive bits
);
Parameters
hbmp
[
in
] Handle to the device
-
dependent bitmap.
cbBuffer
[
in
] Specifies the number of bytes to copy from the bitmap into the buffer.
lpvBits
[
out
] Pointer to a buffer to receive the bitmap bits. The bits are stored
as
an array of
byte
values.
下面是我的代码:
在.net 中定义的拖管方法:
[DllImport(
"
gdi32
"
, CharSet
=
CharSet.Auto)]
static
extern
bool
GetBitmapBits(IntPtr imgFile,
int
cbBuf,
out
byte
[] ImgByte);
其中的第一个参数 IntPtr 我是调用Image.GetHbitmap()取得,但取到的值都是很大的整型,感觉不正常。
System.Drawing.Bitmap bitmap
=
new
System.Drawing.Bitmap(
"
d:\\test.bmp
"
);
IntPtr inp
=
bitmap.GetHbitmap();
调用托管方法
System.Drawing.Bitmap bitmap
=
new
System.Drawing.Bitmap(
"
d:\\test.bmp
"
);
IntPtr inp
=
bitmap.GetHbitmap();
byte
[] imgByte
=
new
byte
[
1024
];
GetBitmapBits(inp,
0
,
out
imgByte);
foreach
(
byte
img
in
imgByte)
{
Console.WriteLine(img.ToString());
}
Console.Read();
以上代码总是出错,找不到原因,现在有以下几个问题请教
1、以上代码在哪个地方错了?
2、GetBitmapBits中的最后一个参数是LPVOID,在.net 中用一个byte数组是否可行?
3、第二个参数是指要复制的字节长度,在我没有得到颜色数组的情况下,我应该给这个参数一个什么值?
希望有了解的朋友能帮助我。研究了1天了。没找到答案。谢谢!
发表于 2005-07-13 11:56
oo复oo
阅读(2618)
评论(7)
编辑
收藏
评论
#1楼
1. 调用GetBitmapBits第二个参数不能为0, 而应该是缓冲区的长度;另, GetHbitmap返回一个句柄, 这个数字是一个很大的数很正常,并不奇怪,呵呵
2. 参考
http://www.pinvoke.net
[DllImport("gdi32.dll")]
static extern int GetBitmapBits(IntPtr hbmp, int cbBuffer,
[Out] byte [] lpvBits);
3. Win32 API -> GetObject
#2楼
[
楼主
]
1、我不知道该函将要取到的颜色数组的长度, 不知有没有好的方法取得,目前我可以先取一个足够大的长度来代替先。
2、就算我用了一个足够大的长度来代替,调用该API仍旧出错。
暂时还无法排除,痛苦啊。能再给写指点吗?
#3楼
你想得到裸数据吧?应该用Bitmap.Lock得到BitmapData,然后通过Unmanaged的方法访问BitmapData.Scan0,或者通过Marshal.Copy复制到数组之后另行处理。
此外,你如此调用会出错应该不奇怪。首先定义里面的out应该改成ref。因为写out的话,CLR会以0(NULL)作为该参数的值传给API(这一点不太确定)。此外在Desktop上面直接将Managed的东西传给Unmanaged的代码是不正确的做法,因为Managed的东西首先位于Local的内存里面,其次是在Managed堆里面。且不论外部进程是否能够访问本地空间,即使能够访问,由于Managed的东西受到托管堆的管理,因此该地址可能随时会发生变化,非常不安全(并且你能够假设这个数组一定是连续的吗?虽然应该是连续的,但是不应该作此假设)。
因此如果你要通过API的方式来调用,也必须通过Marshal.AllocHGlobal来得到申请一段内存,然后将申请到的内存地址作为参数传给GetBitmapBits的第三个参数。
注意,C++里面所描述的[IN]和[OUT]只具有提示作用,有的时候文档的描述并不一定完全正确,因此你得仔细看。一般来说同时具有[IN]和[OUT]的,就应该用ref。但是有的时候会出现文档只标志了[OUT],但是实际上需要用ref。例如这里的GetBitmapBits我估计就是需要用ref而不是out的地方,因为你注意看该参数的描述:
lpvBits
[out] Pointer to a buffer to receive the bitmap bits. The bits are stored as an array of byte values.
注意他说的是Pointer to a buffer *to receive* the bitmap bits,因此一定是一个copy操作,而不是一个return操作。
此外,不建议使用该API,因为这是16位版本的Windows所遗留下来的东西,建议使用GetDIBits。实际上Bitmap.Lock所使用的就是类似GetDIBits的东西,因此最好直接使用.NET Framework提供的方法。
#4楼
纠正,是Bitmap.LockBits,不是Lock
#5楼
原来是这个东东啊? 我早就觉得Bitmap.LockBits有点特殊. 因为试过的GethBitMap 返回的句柄总是变化,想想它是为GDI+生成的一个句柄,是用于创建Image图象的. 不是win32下的句柄.所以想用LockBits,但一查,没找到能实现创建对象的方法.
#6楼
谢谢意sumtec的解释.真是详细.太感谢了,
#7楼
定义没错,用法是错了,更要命的是你居然不懂得GetBitmapBits中的参数是需要通过调用Win32的其他函数来得到的,而你如果为得到这些参数而调用了其他那些Win32位图函数的话,基本上也就不需要使用GetBitmapBits来得到结果了,因为调用的本身已经可以得到比调用GetBitmapBits更多的内容了,包括Bits。
微软声称保留这个函数的目的只是考虑向下兼容,实质上这个函数之所以被保留,完全是某个微软的设计师为方便自己偷懒而已,因为假如你可以假定一些条件的话,这个函数可以一步获得Bits,而用标准的做法去获得Bits是需要分步来做的。嘿嘿,Windows中有很多地方就这样带上了个人色彩。
新用户注册
刷新评论列表
标题
姓名
主页
Email
(博主才能看到)
验证码
*
看不清,换一张
[
登录
][
注册
]
内容(请不要发表任何与政治相关的内容)
网站首页
新闻频道
社区
小组
博问
网摘
闪存
找找看
Remember Me?
登录
使用高级评论
新用户注册
返回页首
恢复上次提交
[使用Ctrl+Enter键可以直接提交]
该文被作者在 2005-07-13 12:10 编辑过
相关文章:
使用Visual Studio2005入门.Net2.0系列视频教程
ASP.NET AJAX入门系列
校内网试水API开放平台
Google Social Graph API智能寻找链接
怎样用在.net2.0里面发送电子邮件?
在.NET中UML一般使用什么软件来做设计
Oracle在.net中sql传参
介绍MS UPnP API
相关链接:
最新IT新闻:
Google股价跌破329美元 61%员工期权价值归零
十年祭:昔日明星软件今何在?
六大可能出售IT企业名单:SUN领头或被猎走
Linux内核2.6.27正式到来
《星际争霸2》一分为三 各种族依次登场
<
2005年7月
>
日
一
二
三
四
五
六
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
公告
自2005年11月4日以来
第
位访问者
佳网工作室
导航
博客园
首页
发新随笔
发新文章
联系
订阅
管理
统计
随笔: 38
文章: 0
评论: 397
引用: 6
与我联系
发短消息
搜索
常用链接
我的随笔
我的空间
我的短信
我的评论
更多链接
我的参与
我的新闻
最新评论
我的标签
留言簿
(1)
给我留言
查看留言
我参与的团队
.NET新手training活动(0/473)
广州.NET俱乐部(0/1741)
ASP.NET AJAX (Atlas)学习(0/1352)
随笔分类
(9)
xml研究
(rss)
读书笔记(2)
(rss)
公告(2)
(rss)
数据结构学习
(rss)
项目源码研究(1)
(rss)
心得(4)
(rss)
随笔档案
(38)
2007年6月 (1)
2006年12月 (1)
2006年5月 (5)
2006年3月 (3)
2006年2月 (4)
2005年12月 (1)
2005年11月 (1)
2005年10月 (2)
2005年7月 (4)
2005年6月 (1)
2005年4月 (5)
2005年3月 (1)
2005年2月 (1)
2004年12月 (2)
2004年11月 (1)
2004年9月 (1)
2004年5月 (4)
相册
个人物品
资料图片
我的其他blog
广州市知微科技有限公司
广州市知微科技有限公司(广州知微科技)成立于2000年7月,是一家专注于高科技产品的民营企业。公司引进国外先进的计算机硬件、软件、网络技术、智能卡等高科技产品,努力开拓国内市场,为国内电信、电力、城建、商业等领域提供最具适用性的全面解决方案和成熟的应用产品。 广州知微科技实行由董事会领导下的总经理负责制,公司下设系统集成部、软件部、市场营销部、财务部。经过多年的锤炼,公司建立了一支勇于开拓、恪守诚信、服务优先的精英团队,现有员工三十余名,其中软件开发工程师23人,技术人员大部分具有硕士及本科学历。 广州知微科技有着良好的商业信誉,广州知微科技已为移动、联通、电力、电台、城建、微软(中国)等多家大型企业提供长期的优质服务,特别是在电信行业软件和服务领域、在软件外包领域,公司具有深厚的基础和丰富的经验。
我的网站
http://www.10nian.cn
PKNow警匪游戏
佳网工作室
源码研究,开放源码,软件开发,随接项目,邮件技术,短信技术,彩信技术,企业建站
图片
邮箱
积分与排名
积分 - 86996
排名 - 468
最新评论
1. re: Sql Server 安装失败,提示"一般性网络错误"
, 只有今天才碰到这个问题! 想想运气也不错啊
--sem
2. re: Ado.net 与NHibernate的关系?
--引用--------------------------------------------------就算是DataSet ,它们的关系还是一样。 Nhibernate同样可以调用DataAda...
--啊啊
3. re: Asp.net Ajax 中的脚本错误: 'Sys'未定义 的解决方法
经过楼主的讲解,'Sys'未定义 是解决了,不过应用了Webpart的程序原来可以在FireFox下拖曳,现在不能拖曳了,在IE中没问题,烦啊!
--codemo
阅读排行榜
1. 你的.net 2.0 真的能与1.1 安全正确地运行在同一台电脑上吗? 小心Server Application Unavailable 错误(11647)
2. .net 2.0 访问Oracle --与Sql Server的差异,注意事项,常见异常(6459)
3. 第一次安装DNN 网站(6015)
4. Sql Server 安装失败,提示"一般性网络错误"(4885)
5. Asp.net Ajax 中的脚本错误: 'Sys'未定义 的解决方法(4196)
评论排行榜
1. 还有要gmail 邮箱的吗? 我的50个邀请权一直没地方用(73)
2. 告别.net ! 2年多了,舍不得!(65)
3. gmail的邀请权原来是用完了又有的啊?(53)
4. 你的.net 2.0 真的能与1.1 安全正确地运行在同一台电脑上吗? 小心Server Application Unavailable 错误(35)
5. Sql Server 安装失败,提示"一般性网络错误"(19)
佳网
广州知微科技有限公司