高分求助,图像合成问题!急!!

hbzxlin 2002-07-08 11:32:57
CPaintDC dc(this);
CBitmap memBitmap;
CDC memDC;
//建立与屏幕显示兼容的内存显示设备
memDC.CreateCompatibleDC(NULL);
CBitmap *pOldBit=memDC.SelectObject(&memBitmap);
//memBitmap.CreateCompatibleBitmap(&dc,800,600);
memBitmap.LoadBitmap(IDB_START);
memDC.SelectObject(&memBitmap);
dc.BitBlt(0,0,800,600,&memDC,0,0,SRCCOPY);

memBitmap.LoadBitmap(IDB_TEMP);
memDC.SelectObject(&memBitmap);
dc.BitBlt(100,100,487,368,&memDC,0,0,SRCAND);
memDC.SelectObject(pOldBit);
CDialog::OnPaint();

问:我希望两层图像融合到一起,与白色部分融合等于原图象,与灰色融合原图象变暗,我的代码运行后为什么显示出来的图像那么难看啊,是不是因为调色板的原因,我该怎么做?谢谢。
...全文
96 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
hbzxlin 2002-07-08
  • 打赏
  • 举报
回复
是啊,所以与白色相AND得到的是原图像啊
duiduiblues 2002-07-08
  • 打赏
  • 举报
回复
与白色相AND得到的怎么能是原图像呢?如果某点是RGB(255,255,255)的话,那么其0x00FFFFFF与任何数相and都不变吧!
hbzxlin 2002-07-08
  • 打赏
  • 举报
回复
结帐!
蒋晟 2002-07-08
  • 打赏
  • 举报
回复
use GDI+ and set Alpha Blend
search GDIPlus and Alpha Blend in MSDN(2001 Oct+)
hbzxlin 2002-07-08
  • 打赏
  • 举报
回复
谢谢!实验成功,但是这个方法不能完全实现我的目标,我要求需要融合到背景上的图片中的白色部分不会影响背景图,这个方法白色图形也会对背景产生影响!
还有别的方法吗?
我的QQ:23385133
MSN:hbzxlin@msn.com
如果方便希望和你联系!
spwnihao 2002-07-08
  • 打赏
  • 举报
回复
不好意思,你要引入一个lib文件。
在你的程序
progect->setting->link->Object/library modules
中加入msimg32.lib
hbzxlin 2002-07-08
  • 打赏
  • 举报
回复
Linking...
testpicDlg.obj : error LNK2001: unresolved external symbol __imp__AlphaBlend@44
Release/testpic.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

MSDN中介绍的要求:
Header: Declared in Wingdi.h; include Windows.h.
Library: Included as a resource in Msimg32.dll.

怎么做啊?!惭愧!

romanticist 2002-07-08
  • 打赏
  • 举报
回复
BitBlt函数方法:

GDI的BitBlt函数的功能是将图形数据块从一个位置搬移到另一个位置,源和目标位图可以在同一个设备文本对象,也可以在不同的设备文本对象,函数原型如下:

BitBlt(HDC hDC,int x,int y,int cx,int cy,HDC hDCSrc,int xSrc,int ySrc,DWORD dwRop);
参数dwRop为光栅操作码,决定位图的显示方式,这里介绍三个下面画透明位图需要用到的的光栅操作码:
光栅操作码:MERGEPAINT
效果:源的反向"或上"目标(即:dest=(NOT src) OR dest)
说明:白色或上任何颜色都等于白色;黑色或上任何颜色颜色都不变

光栅操作码:NOTSRCERASE
效果:源的反向"与上"目标的反向(即:dest=(NOT src) AND (NOT dest))
说明: 黑色与上任何颜色都等于黑色;白色与上任何颜色颜色都不变

光栅操作码:SRCINVERT
效果:源与目标"异或"起来(即:dest=src XOR dest)
说明:黑色与任何颜色异或都等于原来颜色;白色与任何颜色异或都等于原来颜色的反色

例子:先准备一张精灵图片、一张精灵的掩膜图和一张背景图(见下图)



1.用精灵掩膜图处理精灵图片(BitBlt函数用MERGEPAINT光栅操作码):

dcFairy.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcMask,0,0,);
处理过的精灵图片:
2.用精灵掩膜图处理背景(BitBlt函数用NOTSRCERASE光栅操作码)

pDC->BitBlt(x,y,bm.bmWidth,bm.bmHeight,&dcMask,0,0,NOTSRCERASE);
处理过的背景图:
3.把处理过的精灵图片贴到背景上(BitBlt函数用SRCINVERT光栅操作码)

pDC->BitBlt(x,y,bm.bmWidth,bm.bmHeight,&dcFairy,0,0,);
合成后的图形:

完整代码如下:

void DrawFairy(CDC *pDC, int x, int y) // pDC为窗口DC指针
{
CDC dcFairy;
CDC dcMask;
dcFairy.CreateCompatibleDC(pDC);
dcMask.CreateCompatibleDC(pDC);

CBitmap *pMask=dcMask.SelectObject(&m_bmMask); // m_bmMask为精灵掩膜图
CBitmap *pFairy=dcFairy.SelectObject(&m_bmFairy); // m_bmFairy为精灵图片

// 得到精灵图片的大小
BITMAP bm;
m_bmFairy.GetObject(sizeof(bm),&bm);

// 处理精灵图片
dcFairy.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcMask,0,0,MERGEPAINT);

// 处理背景图片(用来贴精灵图片的那一部分)
pDC->BitBlt(x,y,bm.bmWidth,bm.bmHeight,&dcMask,0,0,NOTSRCERASE);

// 将处理过的精灵图片与背景经过处理的部分"异或"起来
pDC->BitBlt(x,y,bm.bmWidth,bm.bmHeight,&dcFairy,0,0,SRCINVERT);

// Release
dcMask.SelectObject(pMask);
dcFairy.SelectObject(pFairy);
}

上面是用BitBlt函数的实现方法,我们也可以用直接操作位图数据缓冲区的方法:

hbzxlin 2002-07-08
  • 打赏
  • 举报
回复
好,谢谢,我试试
spwnihao 2002-07-08
  • 打赏
  • 举报
回复
例子是有,但是太大了,这是我的项目的一小部分,其他的对你也没有用。
你可以自己建一个工程,在两个内存dc上画两幅图像,然后就用这个api函数
不就行了。
spwnihao 2002-07-08
  • 打赏
  • 举报
回复
这个就已经够了,你可以在两个内存dc上分别画图像,然后通过这个api函数就可以了,这是我的项目的一小部分,例子是有但是太大了,也没有什么其它的帮助。你试一下就行了
hbzxlin 2002-07-08
  • 打赏
  • 举报
回复
To spwnihao(海盗):能不能给我一个示例,谢谢!
hbzxlin@inhe.net
master@our.i989.net
hbzxlin 2002-07-08
  • 打赏
  • 举报
回复
谢谢朋友们的帮助,谢谢spwnihao(海盗)!
我指的好看就是能达到Photoshop中图层中混合模式设为正片叠底的效果!
cadinfo 2002-07-08
  • 打赏
  • 举报
回复
你的好看指什么?那么你试着用计算的方法得到某个区域的象素值,
我想应该也是显示的那样,出现的问题是你对算法的估计错误!
何谓融合——就是你提出的And吗?
spwnihao 2002-07-08
  • 打赏
  • 举报
回复
我有一个好办法,我用的效果很好,你试一下吧
CClientDC dc(this);
CDC *memdc;
CBitmap bitmap,pOldbmp;
HBITMAP hbitmap;
memdc=new CDC();
memdc->CreateCompatibleDC(&dc);
hbitmap=(HBITMAP)::LoadImage(NULL,"C:/aa.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
bitmap.Attach(hbitmap);
int bmWidth,bmHeight;
BITMAP bm;
::GetObject(hbitmap,sizeof(bm),&bm);
bmWidth=bm.bmWidth;
bmHeight=bm.bmHeight;
memdc->SelectObject(&bitmap);
BLENDFUNCTION ppfunction;
ppfunction.AlphaFormat=0;
ppfunction.BlendFlags=0;
ppfunction.BlendOp=AC_SRC_OVER;
ppfunction.SourceConstantAlpha=128;
if(::AlphaBlend(dc,100,100,bmWidth,bmHeight,*memdc,0,0,bmWidth,bmHeight,ppfunction)==FALSE)
AfxMessageBox("ERROR");

通过修改ppfunction.SourceConstantAlpha=128;这个值在0-255之间
就可以在两幅图像间调整合成比例参数了

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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