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

How to convert Bitmap to HBITMAP with alpha via Bitmap::GetHBITMAP?

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

为了加载和绘制图像,我一直使用 GDI+,但现在我使用更多 "native" GDI 算法(StretchBlt 等)。

问题是 GDI 无法加载 PNG。我在网上搜索了两种方法:

WIC好像太难了(没想到什么?),所以我选了第一个

使用GDI+加载PNG图像很容易,只需创建一个Bitmap对象,将文件路径传递给构造函数,然后调用getHBITMAP()方法接收HBITMAP句柄,仅此而已。

问题是 Bitmap 生成的 HBITMAP 失去了透明度。

我搜索了如何修复它。有不同的方法——比如将 Color::Black 作为第一个参数传递,等等。但它不起作用。

那么,如何加载 PNG 图像并将其转换为 HBITMAP 具有透明度?

我不使用DrawImage方法,因为它很慢,GDI更快

我固定了代码:

我明白我的错误了:我必须先blit hdc_mem到hdcc,然后再blit图像。我做到了,但是我有一个新问题¬_¬

我做了一个class来管理上传的图片,代码在这里:

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 了,是吗?

发件人:https://ru.whosebug.com/questions/743530

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(;;)
   {
      //here I am downloading via gdi+ bitmap, converting it to hbitmap, writing it to the variable HBITMAP hbm

      if(image==0)
         image = new Image(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 буфер
   }
}