【引用】(转)IPicture、BITMAP、HBITMAP和CBitmap的关系

简介: 【引用】(转)IPicture、BITMAP、HBITMAP和CBitmap的关系

1、有关IPicture加载图片后直接Render到内存DC的问题(HBITMAP 转换 IPicture)


Picture的方法get_Handle可以直接得到图片的句柄


IPicture *pIPicture;
HBITMAP hBitmap;
...
pIPicture->get_Handle((OLE_HANDLE *)&hBitmap);


2、CBitmap 转换 HBITMAP


CBitmap m_bitMap;
HBITMAP m_hBitMap;
m_bitMap.LoadBitmap(IDB_BITMAP);
m_hBitMap=(HBITMAP)m_bitMap.GetSafeHandle();


3、HBITMAP 转换 CBitmap


CBitmap cbMMyBitmap;//用来显示动画的位图
    HBITMAP hMMyHBitmap;//用来显示动画的位图的句柄
    BITMAP bMMyBitmapInfo;//位图信息
    cbMMyBitmap.Attach(hMMyHBitmap);
    cbMMyBitmap.GetBitmap(&bMMyBitmapInfo);


4、DrawDibDraw 和AlphaBlend


一:这两个函数都是绘制 DIB 的。


我在使用过程中发现这两个函数对于 32 位的位图,Alpha通道不能正确显示。就是说,该透明的地方不透明。


说明一下,位图没有问题的,用看图软件或PS之类的都可以正确显示。


我想问一下,是我的原因还是这两个函数本来就不支持32位位图?


ps.显示32位位图可以用AlphaBlend实现的,但是这个函数是绘制场景里的 DDB 的。由于我想显示的是 DIB,不想转来转去的,所以这个函数先不考虑。


二:StretchDIBits 或 DrawDibDraw 就没法显示带透明属性的图片


要显示带透明属性的图片只能用别的方法 例如 GDI+  


5、怎样 样把一个BITMAP结构赋给CBitmap对象


回答(1)


CBitmap::GetBitmap


回答人:软界网友 


回答(2)


每个成员变量都赋值。


回答人:软界网友 


回答(3)


CBitmap::GetBitmap是把CBitmap的信息赋给BITMAP结构


我问的是BITMAP赋给CBitmap


回答人:软界网友 


回答(4)


创建CBitmap对象时,采用BITMAP指定信息


回答人:软界网友 


回答(5)


是用构造函数吗?


CBitmap::CBitmap(BITMAP bitmap)好像没有这个构造函数


回答人:软界网友 


回答(6)


CBitmap::FromHandle(HBITMAP hBitmap )


回答(7)


HBITMAP CreateBitmapIndirect(
CONST BITMAP *lpbm // bitmap data
);


6、用GDI实现位图透明显示


下面是实现中几个关键的地方:

//
把位图bmpFile的特定矩形区域rtWant上的所有像素的数据读取到缓冲区pBuf中
int CChildView::GetPixFromBmp(CString fileName,CRect rtWant,BYTE *pBuf)
{
BITMAPINFOHEADER headInfo;
ZeroMemory(&headInfo,sizeof(headInfo));
int imageHeight;
int imageWidth;
CFile file;
file.Open(fileName, CFile::modeRead);
file.Seek(14, CFile::begin);
file.Read(&headInfo, 40); ///-- 从文件中读去位图的BITMAPINFOHEADER信息
imageWidth = headInfo.biWidth;
imageHeight = headInfo.biHeight;
if(headInfo.biBitCount!=32)
{
   MessageBox(fileName+"不是32位位图");
}
for(int i=0;i < P>
{
   file.Seek(54+(imageHeight-     rtWant.bottom+i)*imageWidth*headInfo.biBitCount/8+rtWant.left*headInfo.biBitCount/8,CFile::begin);
   file.Read(pBuf+i*rtWant.Width()*headInfo.biBitCount/8,rtWant.Width()*headInfo.biBitCount/8);
}
file.Close();
return 0;
}
//


pDesBuf:目的表面缓冲区,W,H--目的表面的宽和高


pSrcBuf: 源表面缓冲区


pRetBuf:结果保存到这个缓冲区中,与pDesBuf兼容


rtBlend:源表面缓冲区与目的表面缓冲区进行alpha混合的矩形区域


alpha : 需要透明的百分比,0---完全透明 ,1 -- 完全不透明

void CChildView::MyBlend(BYTE* pDesBuf,BYTE* pSrcBuf,BYTE* pRetBuf,CRect rtBlend,int W,int H,float alpha)
{
memcpy(pRetBuf,pDesBuf,W*H*4);
for(int i=0;i < P>
{
   for(int j=0;j < P>
   {
    long posDesPix = ((H-rtBlend.bottom+i)*W+rtBlend.left+j)*4;
    long posSrcPix = (i*rtBlend.Width()+j)*4;
    pRetBuf[posDesPix+0] = BYTE(pDesBuf[posDesPix+0]*(1-alpha) + pSrcBuf[posSrcPix+0]*(alpha));
    pRetBuf[posDesPix+1] = BYTE(pDesBuf[posDesPix+1]*(1-alpha) + pSrcBuf[posSrcPix+1]*(alpha));
    pRetBuf[posDesPix+2] = BYTE(pDesBuf[posDesPix+2]*(1-alpha) + pSrcBuf[posSrcPix+2]*(alpha));
    pRetBuf[posDesPix+3] = BYTE(pDesBuf[posDesPix+3]*(1-alpha) + pSrcBuf[posSrcPix+3]*(alpha));
   }
}
}
{
///-- 设置位图的BITMAPINFOHEADER信息
ZeroMemory(&m_headInfo,sizeof(m_headInfo));
m_headInfo.biSize = sizeof(m_headInfo);
m_headInfo.biPlanes = 1;
m_headInfo.biBitCount = 32; // 24
m_headInfo.biCompression = BI_RGB;
m_headInfo.biWidth = m_rtShow.Width();
m_headInfo.biHeight = m_rtShow.Height();
m_headInfo.biSizeImage = m_nLen;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
StretchDIBits(m_MemDC.GetSafeHdc(),0,0,m_rtShow.Width(),m_rtShow.Height(),
   0,0,m_rtShow.Width(),m_rtShow.Height(),(void*)m_pCurrBuf,(BITMAPINFO*)&m_headInfo,NULL,SRCCOPY);
dc.BitBlt(m_rtShow.left,m_rtShow.top,m_rtShow.Width(),m_rtShow.Height(),
   &m_MemDC,0,0,SRCCOPY);
}


相关文章
|
6月前
|
存储 Java
map中存储的是引用,而不是对象本身
该内容是关于Java编程中验证Map存储引用而非复制对象的示例。创建大型List导致内存增加,说明List确实占用空间。通过Person类示例,将不同对象放入Map,改变一个对象的属性后,比较原对象与Map中的键值对,发现两者相等,证明Map保存的是对象引用。
97 5
对象的相等和引用相等的区别
对象的相等和引用相等的区别
|
存储 编译器 C++
<c++> &引用概念 | 引用用法 | 引用与指针区别
<c++> &引用概念 | 引用用法 | 引用与指针区别
189 0
|
JSON Java 数据库
代码重构实战-将值对象改为引用对象(Change Value to Reference)
一个数据结构中可能包含多个记录,而这些记录都关联到同一个逻辑数据结构。例如,我可能会读取一系列订单数据,其中有多条订单属于同一个顾客。遇到这样的共享关系,既能将顾客信息作为值对象看待,也能将其视为引用对象
104 0
|
存储 算法 Java
10-对象的实例化内存布局与访问定位
10-对象的实例化内存布局与访问定位
101 0
10-对象的实例化内存布局与访问定位
|
存储 算法 Java
JVM07_ 对象的实例化、内存布局(对象头、实例数据、对齐填充)、访问定位、直接内存(一)
①. 从字节码角度看待对象的创建过程 ②. 对象的实例化(六个步骤)
158 0
JVM07_ 对象的实例化、内存布局(对象头、实例数据、对齐填充)、访问定位、直接内存(一)
|
存储 Java
JVM07_ 对象的实例化、内存布局(对象头、实例数据、对齐填充)、访问定位、直接内存(二)
③. 对象的内存布局 ①. 对象头(Header) ②. 实例数据(Instance Data) ③. 对齐填充(Padding)
258 0
JVM07_ 对象的实例化、内存布局(对象头、实例数据、对齐填充)、访问定位、直接内存(二)