如何通过 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。我在网上搜索了两种方法:
- 通过 GDI+ 加载
- 使用 WIC。
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 буфер
}
}
我需要绘制具有透明度的 PNG 图像。我使用 GDI、GDI+ 和 WinApi。
为了加载和绘制图像,我一直使用 GDI+,但现在我使用更多 "native" GDI 算法(StretchBlt
等)。
问题是 GDI 无法加载 PNG。我在网上搜索了两种方法:
- 通过 GDI+ 加载
- 使用 WIC。
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 буфер
}
}