Winapi 如何通过Bitmap::GetHBITMAP将位图转换为带有alpha的HBITMAP?

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句柄即可 问题是由

我需要绘制具有透明度的PNG图像。我使用GDI、GDI+和WinApi

为了加载和绘制图像,我一直使用GDI+,但现在我使用的是更多的“本地”GDI算法(
StretchBlt
,等等)

问题是GDI无法加载PNG。我搜索了互联网,找到了两种方法:

  • 通过GDI加载+
  • 使用WIC
WIC似乎太难了(但我期待什么呢?),所以我选择了第一个

使用GDI+加载PNG图像很容易,只需创建一个
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.com

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.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混合快得多。鉴于代码,不清楚您真正需要什么。代码(就像它的格式)被严重破坏了。拿一份佩佐德的。