StretchDIBits打印,红色变成了蓝色,蓝色变成了红色

fengrx 2010-01-26 01:46:31
下面是我的代码。

BITMAPINFOHEADER bmih;
bmih.biSize = sizeof(bmih);
bmih.biHeight = -bmpDy;
bmih.biWidth = bmpDx;
bmih.biPlanes = 1;
// we could create this dibsection in monochrome
// if the printer is monochrome, to reduce memory consumption
// but splash is currently setup to return a full colour bitmap
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = bmih.biClrImportant = 0;
unsigned char* bmpData = bmp->data();

//::SetStretchBltMode(hdc,COLORONCOLOR);
::StretchDIBits(hdc,
// destination rectangle
leftMargin, topMargin, pageDx, pageDy,
// source rectangle
0, 0, bmpDx, bmpDy,
bmpData,
(BITMAPINFO *)&bmih,
DIB_RGB_COLORS,
SRCCOPY);


此问题在部分彩色打印机上有问题(如:hp2605)。
...全文
1067 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
bobob 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 boksic 的回复:]
在windows下rgb是反向存储的,也就是说在文件中存的实际上是bgr,这会导致r和b反向
所以可以用个函数把这两个颜色互换一下

我提供一个速度比较快的函数
void flipIt(void* buffer)
{
void* b = buffer;
__asm
{
mov ecx, 256*256
mov ebx, b
label:
mov al,[ebx+0]
mov ah,[ebx+2]
mov [ebx+2],al
mov [ebx+0],ah

add ebx,3
dec ecx
jnz label
}
}

[/Quote]
void flipIt(void* buffer,long nSize)
{
void* b = buffer;
__asm
{
mov ecx, nSize
mov ebx, b
label:
mov al,[ebx+0]
mov ah,[ebx+2]
mov [ebx+2],al
mov [ebx+0],ah

add ebx,3
dec ecx
jnz label
}
}
改成这样就通用了
boksic 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 boksic 的回复:]
在windows下rgb是反向存储的,也就是说在文件中存的实际上是bgr,这会导致r和b反向
所以可以用个函数把这两个颜色互换一下

我提供一个速度比较快的函数
void flipIt(void* buffer)
{
void* b = buffer;
__asm
{
mov ecx, 256*256
mov ebx, b
label:
mov al,[ebx+0]
mov ah,[ebx+2]
mov [ebx+2],al
mov [ebx+0],ah

add ebx,3
dec ecx
jnz label
}
}

[/Quote]





补充一下:
所以我觉得
在不同的打印机上,有些采用little endian 有些采用big endian 从而会导致蓝红反向
boksic 2010-01-27
  • 打赏
  • 举报
回复
在windows下rgb是反向存储的,也就是说在文件中存的实际上是bgr,这会导致r和b反向
所以可以用个函数把这两个颜色互换一下

我提供一个速度比较快的函数
void flipIt(void* buffer)
{
void* b = buffer;
__asm
{
mov ecx, 256*256
mov ebx, b
label:
mov al,[ebx+0]
mov ah,[ebx+2]
mov [ebx+2],al
mov [ebx+0],ah

add ebx,3
dec ecx
jnz label
}
}
bobob 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 fengrx 的回复:]
引用 25 楼 bobob 的回复:
看代码,楼主是打印PDF吧?你这样打问题很多的,尤其高精度打印机、针式打印机
普通的打印机还凑合,但是也随时会出现StretchDIBits失败的情况,这个函数太脆弱了


PDF引擎渲染完成后是一个DIB的24位,分辨率72DPI的图像数据。
我要将他打印,其他有什么方法呢?

要求打印结果和显示是1:1的,上面有公章图片,大小不能变。所以我在打印时,为了打印效果凑合、打印速度也可以,根据实际的打印机分辨率,对图像进行了缩放。
[/Quote]
这样做,第一个问题,打印质量很差,尤其高精度打印机,很明显,当然,这个不是致命的问题
第二个,某些打印机不支持缩放位图的
bobob 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 fengrx 的回复:]
引用 24 楼 bobob 的回复:
明显是反色了
你把图像数据变成倒序,然后把高度指定为正数,试试
打印机程序,真的没多少道理可讲,因为各家的驱动都是自己开发的,打印机驱动有毛病很正常


图像数据变成倒序,其他正确的打印机又会出问题。

高度变正数,图像是反着的。
[/Quote]
变成倒序和高度指定为正数是需要同时做的,只改一个当然还是有问题
BMP图像数据一般是从下往上存储,第一行看到的数据其实是放在最下面
如果数据是从上往下放的,那就要指定高度为负数
我的意思是,你先把图像数据从下往上放,然后把高度指定成正数,这样做的目的是把位图数据构造称最普通的形式,因为我怀疑是打印机驱动处理高度为负的情况的时候把RGB顺序搞反了
fengrx 2010-01-27
  • 打赏
  • 举报
回复
请教大家一个问题,是不是StretchDIBits调用是,只能使用MM_TEXT模式。使用MM_LOMETRIC会有问题。
fengrx 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 bobob 的回复:]
看代码,楼主是打印PDF吧?你这样打问题很多的,尤其高精度打印机、针式打印机
普通的打印机还凑合,但是也随时会出现StretchDIBits失败的情况,这个函数太脆弱了
[/Quote]

PDF引擎渲染完成后是一个DIB的24位,分辨率72DPI的图像数据。
我要将他打印,其他有什么方法呢?

要求打印结果和显示是1:1的,上面有公章图片,大小不能变。所以我在打印时,为了打印效果凑合、打印速度也可以,根据实际的打印机分辨率,对图像进行了缩放。
fengrx 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 bobob 的回复:]
明显是反色了
你把图像数据变成倒序,然后把高度指定为正数,试试
打印机程序,真的没多少道理可讲,因为各家的驱动都是自己开发的,打印机驱动有毛病很正常
[/Quote]

图像数据变成倒序,其他正确的打印机又会出问题。

高度变正数,图像是反着的。
fandh 2010-01-27
  • 打赏
  • 举报
回复
楼主的问题,看样子还得继续想办法!bobob说的有道理,你换一种方式试试!
LPR_Pro 2010-01-27
  • 打赏
  • 举报
回复
学习
bobob 2010-01-27
  • 打赏
  • 举报
回复
看代码,楼主是打印PDF吧?你这样打问题很多的,尤其高精度打印机、针式打印机
普通的打印机还凑合,但是也随时会出现StretchDIBits失败的情况,这个函数太脆弱了
bobob 2010-01-27
  • 打赏
  • 举报
回复
明显是反色了
你把图像数据变成倒序,然后把高度指定为正数,试试
打印机程序,真的没多少道理可讲,因为各家的驱动都是自己开发的,打印机驱动有毛病很正常
fengrx 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 ga6840 的回复:]
保存个位图文件可以正常显示吗?
[/Quote]

同一个机器,两个打印机,一个正常,一个不正常。如果图片有问题,那应该都有问题吧。
还有就是,共实施了30个点,只有这一个地方有问题。
由于还要继续实施,所以需要解决此问题,怕其他地方出现。
fengrx 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 cnzdgs 的回复:]
不是所有打印机都支持StretchDIBits的,调用GetDeviceCaps检查一下。
[/Quote]

我代码中CheckPrinterStretchDibSupport函数中就是做的这个操作。只有在支持时才执行的打印操作。
fengrx 2010-01-27
  • 打赏
  • 举报
回复
请 bobob 到下面帖子中去领分。

http://topic.csdn.net/u/20100126/14/7e7b3ddb-93d7-4e75-a741-cdaa836788a1.html

另外,非常感谢fandh的积极帮助,接分。
fengrx 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 bobob 的回复:]
引用 28 楼 fengrx 的回复:
引用 24 楼 bobob 的回复:
明显是反色了
你把图像数据变成倒序,然后把高度指定为正数,试试
打印机程序,真的没多少道理可讲,因为各家的驱动都是自己开发的,打印机驱动有毛病很正常


图像数据变成倒序,其他正确的打印机又会出问题。

高度变正数,图像是反着的。

变成倒序和高度指定为正数是需要同时做的,只改一个当然还是有问题
BMP图像数据一般是从下往上存储,第一行看到的数据其实是放在最下面
如果数据是从上往下放的,那就要指定高度为负数
我的意思是,你先把图像数据从下往上放,然后把高度指定成正数,这样做的目的是把位图数据构造称最普通的形式,因为我怀疑是打印机驱动处理高度为负的情况的时候把RGB顺序搞反了
[/Quote]

非常感谢 bobob ,和你说的一样。问题解决,马上散分。
ga6840 2010-01-26
  • 打赏
  • 举报
回复
保存个位图文件可以正常显示吗?
cnzdgs 2010-01-26
  • 打赏
  • 举报
回复
不是所有打印机都支持StretchDIBits的,调用GetDeviceCaps检查一下。
fengrx 2010-01-26
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 fandh 的回复:]
你现在用虚拟打印机,也是颜色不一样么?
[/Quote]

我用虚拟机可以,是正常的。
这个问题只有在用户现场的一个打印机上出现了问题。
fandh 2010-01-26
  • 打赏
  • 举报
回复
你现在用虚拟打印机,也是颜色不一样么?
加载更多回复(17)

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧