Winapi 如何通过Bitmap::GetHBITMAP将位图转换为带有alpha的HBITMAP?
我需要绘制具有透明度的PNG图像。我使用GDI、GDI+和WinApi 为了加载和绘制图像,我一直使用GDI+,但现在我使用的是更多的“本地”GDI算法(Winapi 如何通过Bitmap::GetHBITMAP将位图转换为带有alpha的HBITMAP?,winapi,bitmap,gdi+,gdi,Winapi,Bitmap,Gdi+,Gdi,我需要绘制具有透明度的PNG图像。我使用GDI、GDI+和WinApi 为了加载和绘制图像,我一直使用GDI+,但现在我使用的是更多的“本地”GDI算法(StretchBlt,等等) 问题是GDI无法加载PNG。我搜索了互联网,找到了两种方法: 通过GDI加载+ 使用WIC WIC似乎太难了(但我期待什么呢?),所以我选择了第一个 使用GDI+加载PNG图像很容易,只需创建一个Bitmap对象,将文件路径传递给构造函数,然后调用getHBITMAP()方法接收HBITMAP句柄即可 问题是由
StretchBlt
,等等)
问题是GDI无法加载PNG。我搜索了互联网,找到了两种方法:
- 通过GDI加载+
- 使用WIC
Bitmap
对象,将文件路径传递给构造函数,然后调用getHBITMAP()
方法接收HBITMAP
句柄即可
问题是由Bitmap
生成的HBITMAP
失去透明度
我在寻找如何修理它。有不同的方法,比如将Color::Black
作为第一个参数传递,等等,但它不起作用
那么,我如何读取PNG图像并将其转换为透明的HBITMAP
我不使用DrawImage方法,因为它速度慢,GDI速度快
我锁定了密码:
class Imagee
{
HDC hdc; HBITMAP bm;
Imagee(HDC hdc, HBITMAP bm, another args)
{
this->hdc=CreateCompatibleDC(hdc);
this->bm=bm;
SelectObject(this->hdc,this->bm);
}
void draw(int hdcc, int x,int y, int cx, int cy)
{
**StretchBlt(this->hdc,0,0,cx,cy,hdcc,x,y,cx,cy,SRCCOPY); //I'VE ADDED THIS
SelectObject(this->hdc,this->bm); //AND THIS **
StretchBlt(this->hdcc,x,y,cx,cy,hdc,0,0,cx,cy,SRCCOPY);
};
};
Imagee *image;
void render()
{
for(;;)
{
//some draws
//Loading a bitmap via Gdi+, calling a GetHBITMAP function, HBITMAP variable named hbm
if(image==0)
image=new Imagee(hdc_mem, hbm, x, y etc..);
image->draw(hdc_mem, x, y etc..);
StretchBlt(hdc_main,0,0,1920,1080,hdc_mem,0,0,1920,1080,SRCCOPY);
}
我理解我的错误:我必须先将hdc_mem blit到hdcc,然后再blit图像。我做到了,但我有一个新问题
我制作了一个类来管理上传的图像,下面是代码:
class Imagee
{
HDC hdc; HBITMAP bm;
Imagee(HDC hdc, HBITMAP bm, another args)
{
this->hdc=CreateCompatibleDC(hdc);
this->bm=bm;
SelectObject(this->hdc,this->bm);
}
void draw(int hdcc, int x,int y, int cx, int cy)
{
**StretchBlt(this->hdc,0,0,cx,cy,hdcc,x,y,cx,cy,SRCCOPY); //I'VE ADDED THIS
SelectObject(this->hdc,this->bm); //AND THIS **
StretchBlt(this->hdcc,x,y,cx,cy,hdc,0,0,cx,cy,SRCCOPY);
};
};
Imagee *image;
void render()
{
for(;;)
{
//some draws
//Loading a bitmap via Gdi+, calling a GetHBITMAP function, HBITMAP variable named hbm
if(image==0)
image=new Imagee(hdc_mem, hbm, x, y etc..);
image->draw(hdc_mem, x, y etc..);
StretchBlt(hdc_main,0,0,1920,1080,hdc_mem,0,0,1920,1080,SRCCOPY);
}
我有一个黑屏。看来我不能再调用SelectObject了,是吗?Solve
class Imagee
{
HDC hdc; HBITMAP bm;
Imagee(HDC hdc, HBITMAP bm, another args)
{
this->hdc=CreateCompatibleDC(hdc);
this->bm=bm;
SelectObject(this->hdc,this->bm);
}
void draw(int hdcc, int x,int y, int cx, int cy)
{
BITMAP btm;
GetObject(bm,sizeof(BITMAP),&btm)
BLENDFUNCTION bf
//initialize bf
AlphaBlend(hdcc,x,y,cx,cy,his->hdcc,0,0,btm.bmWidth,btm.bmHeight,bf);
};
};
Imagee *image;
void render()
{
for(;;)
{
//здесь я загружая через гди+ битмам, конвертирую его в хбитмап, записывая в перменную HBITMAP hbm
if(image==0)
image=new Imagee(hdc_mem, hbm, x, y и т.д.);
image->draw(hdc_mem, x, y и т.д.);
StretchBlt(hdc_main,0,0,1920,1080,hdc_mem,0,0,1920,1080,SRCCOPY); //hdc_main главный дс, hdc_mem буфер
}
}
感谢ru.stackoverflow.comSolve
class Imagee
{
HDC hdc; HBITMAP bm;
Imagee(HDC hdc, HBITMAP bm, another args)
{
this->hdc=CreateCompatibleDC(hdc);
this->bm=bm;
SelectObject(this->hdc,this->bm);
}
void draw(int hdcc, int x,int y, int cx, int cy)
{
BITMAP btm;
GetObject(bm,sizeof(BITMAP),&btm)
BLENDFUNCTION bf
//initialize bf
AlphaBlend(hdcc,x,y,cx,cy,his->hdcc,0,0,btm.bmWidth,btm.bmHeight,bf);
};
};
Imagee *image;
void render()
{
for(;;)
{
//здесь я загружая через гди+ битмам, конвертирую его в хбитмап, записывая в перменную HBITMAP hbm
if(image==0)
image=new Imagee(hdc_mem, hbm, x, y и т.д.);
image->draw(hdc_mem, x, y и т.д.);
StretchBlt(hdc_main,0,0,1920,1080,hdc_mem,0,0,1920,1080,SRCCOPY); //hdc_main главный дс, hdc_mem буфер
}
}
多亏了ru.stackoverflow.com你为什么需要借助GDI进行绘图?您可以为
HDC
创建Graphics
对象,然后将Bitmap
传递给Graphics::DrawImage()
。请参阅GDI+文档中的。如果必须使用GDI,请参见。GDI+将以透明方式绘制png。你还没有表现出你有什么问题。GDI函数不理解alpha,但在某些特殊情况下,您可以使用GetHBITMAP(Gdiplus::Color::Transparent,&hBitmap)
。@Remy Lebeau GDI绘制图像的速度比DrawImage快method@BarmakShemirani我也试过颜色::透明,它不起作用(我的意思是没有透明度)SRCCOPY
不执行alpha混合。一个简单的块传输(这是SRCCOPY
所做的)比alpha混合快得多。鉴于代码,不清楚您真正需要什么。代码(就像它的格式)被严重破坏了。找一份Petzold的。为什么你需要借助GDI来画画?您可以为HDC
创建Graphics
对象,然后将Bitmap
传递给Graphics::DrawImage()
。请参阅GDI+文档中的。如果必须使用GDI,请参见。GDI+将以透明方式绘制png。你还没有表现出你有什么问题。GDI函数不理解alpha,但在某些特殊情况下,您可以使用GetHBITMAP(Gdiplus::Color::Transparent,&hBitmap)
。@Remy Lebeau GDI绘制图像的速度比DrawImage快method@BarmakShemirani我也试过颜色::透明,它不起作用(我的意思是没有透明度)SRCCOPY
不执行alpha混合。一个简单的块传输(这是SRCCOPY
所做的)比alpha混合快得多。鉴于代码,不清楚您真正需要什么。代码(就像它的格式)被严重破坏了。拿一份佩佐德的。