16位色深屏幕下,可以绘出32位色深的图形吗?

sunlin7 2010-11-25 11:33:46
今晚搞了一晚上,没有什么进展,特来向大家求教:
ShockWaveFlash控件的IViewObject->Draw()函数在HDC上绘图,屏幕色深为32位时,可以正确绘制带有Alpha通道的图形,当屏幕色深调整为16位的时候,同样代码,Draw()函数得到的图形的Alpha通道内容不正确。

问有没有办法设置DC信息,让依赖于DC信息的函数在16位色深模式下,认为hdc是在32位颜色深度模式,从而得到正确的结果?

(现在是使用vs2008在一个对话框中插入flash控件,并设置WMode为Transparent,
重写对话框的OnPaint函数:
void Ctemp03Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
// CDialog::OnPaint();
CPaintDC dc(this);
RECT rcTotal;
::GetClientRect(m_hWnd, &rcTotal);
BITMAPINFOHEADER bih = { 0 };
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = rcTotal.right - rcTotal.left;
bih.biHeight = (rcTotal.bottom - rcTotal.top); // use screen axis
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
HDC hdcBack = CreateCompatibleDC ( 0 );
char *m_lpBitsOnly = 0;
HBITMAP bmpBack = CreateDIBSection( 0, (PBITMAPINFO)&bih, DIB_RGB_COLORS, (void **)&m_lpBitsOnly, NULL, 0x0);
HGDIOBJ hOldObj = ::SelectObject(hdcBack, bmpBack);
CDC hello;
hello.Attach(hdcBack);
PaintWindowlessControls(&hello);
BLENDFUNCTION blendFunc = {AC_SRC_OVER, 0, 0xFF, AC_SRC_ALPHA };
::AlphaBlend(dc.GetSafeHdc(), 0, 0, bih.biWidth, bih.biHeight, hdcBack, 0, 0, bih.biWidth, bih.biHeight, blendFunc );
::SelectObject(hdcBack, hOldObj);
::DeleteObject(bmpBack);
//FILE *f = fopen("d:\\b.bin", "wb");
//fwrite(m_lpBitsOnly, 1, bih.biWidth*bih.biHeight*4, f);
//fclose(f);
//}
}
}

这样在16位色深屏幕下面,得到的结果不正确。

使用gimp以Raw Image模式打开注释掉的写文件代码产生d:\b.bin文件,可以明确看到,16bit color模式下,alpha通道全部为零,显然不是需要的结果,而在32bit color模式下面,alpha通道没有问题。)
...全文
524 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
jyh_baoding 2010-12-04
  • 打赏
  • 举报
回复
有点难度,现在的技术设备好象没必要费这个精力啊
laviewpbt 2010-12-04
  • 打赏
  • 举报
回复
怎么那么小的图啊





laviewpbt 2010-12-04
  • 打赏
  • 举报
回复
当屏幕色深改为16位时,GDI的绘图函数都会受到影响,比如下图:



但是似乎GDI+的DrawImage函数不受影响,比如这个蜘蛛:


sunlin7 2010-12-03
  • 打赏
  • 举报
回复
CreateDC应该是一个可行的办法。
我前面用CreateDC("DISPLAY",...)这样简单的试过,没有成功(是在没有装显卡驱动的机器上),可能是我的参数没有填写正解,也可能是创建后还需要进行相关的设置。
傻X 2010-12-03
  • 打赏
  • 举报
回复
个人认为(仅仅是猜测)
因为楼主用的是CreateCompatibleDC因此,DC的设置肯定是当前的屏幕显卡显示的模式.
是否可以用CreateDC来创建呢?
刚刚查了下DEVMODE里面确实是可以选择的 dmBitsPerPel参数
向立天 2010-12-03
  • 打赏
  • 举报
回复
恐怕没有什么简便的方法
至少我不知道
以前用Ddraw做游戏的时候都是自己计算alpha通道的
辰岡墨竹 2010-12-03
  • 打赏
  • 举报
回复
直接CreateDC那样会导致一些颜色褪色错误,16位色深下貌似用DrawDib函数组绘制可以自动褪色的样子。
hongkun18 2010-12-03
  • 打赏
  • 举报
回复
默默学习...
baby393 2010-12-03
  • 打赏
  • 举报
回复
真的是无语了,只要屏幕的色深没有改变,你Create什么DC都没有用。
babala2009 2010-12-03
  • 打赏
  • 举报
回复
lisunlin0 你的头像 好像和csdn谁的一样!!!!!!!!!!!!!!!!!!!!!!!!!!
sunlin7 2010-12-02
  • 打赏
  • 举报
回复
上面列出代码的尾部有将图像存储到d:\b.bin的操作,使用gimp打开,可以看到flash绘制出的图形。

图形不仅仅是要显示出来,一方面需要使用flash绘出图形所带的alphpa值融合到另一幅图像上,另一方面也要能保存到本地,供其它程序使用(仍然要求带有正确的alpha通道)。

可见对alpha通道的要求非常的强硬,必须得到32bit的、带有正确alpha通道的图像, 没有其它的办法可以绕行。

在32位屏幕色深时上面代码没有问题。

在16位屏幕色深的情况下,以上代码得到的flash控件绘出的图形r,g,b没有问题,但alpha通道为0.

现使用ddraw的surface锁定表面为32位,可以勉强解决问题。

问:有无其它更简单的办法(比如设置CompatibleDC的某种属性)使得代码得到带有正确alpha通道信息的图形。
ameyume 2010-12-02
  • 打赏
  • 举报
回复
这个类似有点像素差值的味道
看来只能通过自己计算来实现了。
向立天 2010-12-02
  • 打赏
  • 举报
回复
如果你只是想通过一种方式在16位的屏幕上输出32的资源图片
我觉得最合理的就是进行内存转换
也就是通过一种方式将图片转成16的
beaugauge2010 2010-12-02
  • 打赏
  • 举报
回复
16位色深是应用在什么场合?
sunlin7 2010-12-01
  • 打赏
  • 举报
回复
是我没有说清楚,代码中使用CreateDIBSection创建32bit的DIB,并SelectObject到CompatibleDC 上面。现在因为屏幕色深是16位的,所以CompatibleDC有调色板,并且是与屏幕匹配的(当然可以使用调色板管理函数进行管理,但仍然无法适应32bit的真彩色情况)。
我目前是使用DDraw的surface强制锁定表面为32位的,勉强解决了问题,但总觉得可能有更好的办法来做这个。
jameshooo 2010-12-01
  • 打赏
  • 举报
回复
16位的格式是什么?565?1555?失真是必然的,有的格式没有A通道,有的格式只能指示是否透明。
baby393 2010-12-01
  • 打赏
  • 举报
回复
问你一个问题:256色的屏幕可以正确显示32位色的图象吗?

16位色不包含ALPHA通道,只能近似模拟。
sunlin7 2010-11-29
  • 打赏
  • 举报
回复
pady_pady 2010-11-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hastings 的回复:]
看来得自己使用AlphaBlend的公式来循环遍历图素位数据自己计算了~~
[/Quote]
看来只能逐点自己计算了,不能用api了
witchman___ 2010-11-26
  • 打赏
  • 举报
回复
屏幕的模式决定了,应该是不可以吧,等待高手...
加载更多回复(1)
NEO SDK是一个跨平台的免费开源图形软件开发包。它支持基本绘图、多种格式图形显示、鼠标操 作、扩展内存和扩充内存的操作、时钟、音频播放、多种字体的汉字及英文显示等等特性;更激动人心的是, 它可以工作于高分辨率下(比如800X600、1024X768甚至1280X1024);而且,它支持最高24位的各种! 并拥有不错的处理速度。NEO中的函数调用接口大部分与Allegro相似,为你的代码向Allegro移植作准备。 NEO开放所有源代码,因为我认为这样更利于让大家发现BUG,利于NEO的成长。希望你能喜欢。 本开发包主要拥有以下特性: 1、支持320X200,640X400,640X480,800X600,1024X768,1280X1024等各种标准分辨率, 以及各种诸如320X240,320X400,512X512等ModeX分辨率; 2、全面支持8位256色,15位32768色,16位即65536色三种模式,在Windows等平台下还支持24位; 3、齐全的基本的绘图函数,让你轻松绘制象点、线、方、圆等等各种简单的图形; 4、支持多种格式图形的显示,在这一版里,支持BMP、ICO和CUR的显示; 5、支持鼠标操作,并集成一套功能强大高级鼠标控制函数,譬如能够检测双击,还支持使用ICO\CUR 文件作为光标等; 6、拥有一套高级键盘处理函数,用户可以通过安装键盘中断来使用它们; 7、集成时钟控制函数,主要用于游戏开发,你也可以将鼠标与时钟绑定,便于鼠标的操作(和 Allegro相似); 8、在DOS下支持扩展内存和扩充内存的操作,便于开发需要大内存的程序; 9、可以显示多种字体的英文和中文,并支持一些文字特效; 10、拥有基于常规内存、扩展内存、显存、虚拟内存的多套显示内核,执行程序运行时可根据用户机器 的具体环境自动选择最佳的内核,以保证最好的兼容性; 11、支持矩形输出裁剪,让动画等各种显示特效均成为可能; 12、支持类似 Borland graphics.h 中库函数的作图模式,譬如XOR异或模式; 13、兼容 Borland graphics.h 中的大部分函数以方便将原来使用graphics.h的程序移植到NEO中来; 14、强大的错误处理系统,能根据用户的设置决定输出错误信息的方式,譬如直接在屏幕上显示还是 输出到错误日志,或者仅仅只用喇叭报一下警; 15、完备的编译开关组,让你有选择的采用所需的部分功能,减少可执行文件的大小,加快编译速度; 16、强大快速的调色板操作函数,可以实现淡出淡入特效,还能够使用8位色彩分量长的调色板, 还可以实现64级调色板之间的过渡; 17、支持通过声卡播放WAV文件,让你的程序更加绘声绘色; 18、提供了多图形缓冲页架构,并支持高效率的硬件换页机制和滚屏机制; 19、支持诸如翻折,灰度,半透明,模糊,反色,颜色加强等多种图形显示特效; 20、完备的周边辅助程序、示例和各种模板及插件,让你的开发过程更为简单方便; 21、全面支持Borland全系列C\C++编译器及DEV-CPP,部分支持VC++ 1.5编译环境; 你现在所看到的版本,是NEO SDK的最终版本,我决定停止对它的一切开发和维护工作,并不再提供官方的技术支持。
NEO SDK是一个跨平台的免费开源图形软件开发包。它支持基本绘图、多种格式图形显示、鼠标操 作、扩展内存和扩充内存的操作、时钟、音频播放、多种字体的汉字及英文显示等等特性;更激动人心的是, 它可以工作于高分辨率下(比如800X600、1024X768甚至1280X1024);而且,它支持最高24位的各种! 并拥有不错的处理速度。NEO中的函数调用接口大部分与Allegro相似,为你的代码向Allegro移植作准备。 NEO开放所有源代码,因为我认为这样更利于让大家发现BUG,利于NEO的成长。希望你能喜欢。 本开发包主要拥有以下特性: 1、支持320X200,640X400,640X480,800X600,1024X768,1280X1024等各种标准分辨率, 以及各种诸如320X240,320X400,512X512等ModeX分辨率; 2、全面支持8位256色,15位32768色,16位即65536色三种模式,在Windows等平台下还支持24位; 3、齐全的基本的绘图函数,让你轻松绘制象点、线、方、圆等等各种简单的图形; 4、支持多种格式图形的显示,在这一版里,支持BMP、ICO和CUR的显示。在以后的版本中, 还会陆续增加对PCX、GIF、TGA等格式的支持; 5、支持鼠标操作,并集成一套功能强大高级鼠标控制函数,譬如能够检测双击,还支持使用ICO\CUR 文件作为光标等; 6、拥有一套高级键盘处理函数,用户可以通过安装键盘中断来使用它们; 7、集成时钟控制函数,主要用于游戏开发,你也可以将鼠标与时钟绑定,便于鼠标的操作(和 Allegro相似); 8、在DOS下支持扩展内存和扩充内存的操作,便于开发需要大内存的程序; 9、可以显示多种字体的英文和中文,并支持一些文字特效; 10、拥有基于常规内存、扩展内存、显存、虚拟内存的多套显示内核,执行程序运行时可根据用户机器 的具体环境自动选择最佳的内核,以保证最好的兼容性; 11、支持矩形输出裁剪,让动画等各种显示特效均成为可能; 12、支持类似 Borland graphics.h 中库函数的作图模式,譬如XOR异或模式; 13、兼容 Borland graphics.h 中的大部分函数以方便将原来使用graphics.h的程序移植到NEO中来; 14、强大的错误处理系统,能根据用户的设置决定输出错误信息的方式,譬如直接在屏幕上显示还是 输出到错误日志,或者仅仅只用喇叭报一下警; 15、完备的编译开关组,让你有选择的采用所需的部分功能,减少可执行文件的大小,加快编译速度; 16、强大快速的调色板操作函数,可以实现淡出淡入特效,还能够使用8位色彩分量长的调色板, 还可以实现64级调色板之间的过渡; 17、支持通过声卡播放WAV文件,让你的程序更加绘声绘色; 18、提供了多图形缓冲页架构,并支持高效率的硬件换页机制和滚屏机制; 19、支持诸如翻折,灰度,半透明,模糊,反色,颜色加强等多种图形显示特效; 20、完备的周边辅助程序、示例和各种模板及插件,让你的开发过程更为简单方便; 21、全面支持Borland全系列C\C++编译器及DEV-CPP,部分支持VC++ 1.5并还将移植到其它各平台的编译环境; 在NEO的后续版本中,还会增加对图形用户接口(GUI) 的支持,对Alpha效果的 支持等等,让你感受一个强大的NEO SDK! <更多的详细内容请阅读docs文件夹中的教程>

15,979

社区成员

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

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