【发布时间】:2020-10-09 03:03:51
【问题描述】:
我在按下按钮时尝试打印 .bmp,但此图像必须具有“透明度”。
我想过改变每个像素的颜色。这个 .bmp 将在另一个之前,所以我想做的是:从后面的 .bmp 中获取像素的颜色,并用它们绘制前面的背景。。 p>
问题:
我想这可以做到,考虑到 .bmp 的背景是白色的,只是识别一个像素是否是白色并改变它的颜色。
但是,我没有成功尝试这样做... 我尝试了几个参考资料来作为自己的基础,但都没有奏效。
我尝试过this one:我尝试编辑它以将 .bmp 的背景像素(当它们为白色时)更改为它后面的 .bmp 的像素。 我没有成功,像素都乱码了。
我也试过this one:图像是黑白的(这已经在下面的 cmets 中解释过)。
我还没有找到基于位图的 TransparentBlt() 函数使用示例,我已经尝试使用它,但图像保持不变。 这是我的全部代码:
#define _WIN32_WINNT 0x0500 /* tem ficar na primeira linha do código */
#define WINVER 0x0600
#include <windows.h>
#include <wingdi.h>
#define WM_CREATE 0x0001
#define WM_DESTROY 0x0002
#define ID_IMAGE1 1
#define ID_IMAGE2 2
#define ID_IMAGE3 3
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void LoadMyImage(void);
void LoadMyImage2(void);
void LoadMyImage3(void);
HBITMAP hBitmap;
HBITMAP hBitmap2;
HBITMAP hBitmap3;
POINT posicao;
int x, y;
HWND hWnd = GetConsoleWindow();
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow) {
MSG msg;
WNDCLASSW wc = {0};
wc.lpszClassName = L"Static image";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0,IDC_ARROW);
RegisterClassW(&wc);
CreateWindowW(wc.lpszClassName, L"MLG antivirus",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 1001, 601, 0, 0, hInstance, 0);
ShowWindow(hWnd, SW_MINIMIZE);
//won't hide the window without SW_MINIMIZE
ShowWindow(hWnd, SW_HIDE);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
HWND hsti;
HWND hBitmapButton;
HWND hitm;
switch(msg) {
case WM_CREATE:
LoadMyImage();
hsti = CreateWindowW(L"Static", L"",
WS_CHILD | WS_VISIBLE | SS_BITMAP,
0, 0, 300, 300, hwnd, (HMENU) ID_IMAGE1, NULL, NULL);
SendMessage(hsti, STM_SETIMAGE,
(WPARAM) IMAGE_BITMAP, (LPARAM) hBitmap);
LoadMyImage2();
hBitmapButton = CreateWindowW(L"BUTTON", L"", WS_CHILD | WS_VISIBLE
| BS_PUSHBUTTON | BS_BITMAP,
334, 291, 316, 136, hwnd, (HMENU)ID_IMAGE2, NULL, NULL);
SendMessage(hBitmapButton, BM_SETIMAGE,
(WPARAM) IMAGE_BITMAP, (LPARAM) hBitmap2);
break;
case WM_COMMAND:
if (LOWORD(wParam) == ID_IMAGE2) {
GetCursorPos(&posicao);
x = posicao.x-127;
y = posicao.y-150;
LoadMyImage3();
hitm = CreateWindowW(L"Static", L"",
WS_CHILD | WS_VISIBLE | SS_BITMAP,
x, y, 38, 38, hwnd, (HMENU) ID_IMAGE3, NULL, NULL);
SendMessage(hitm, STM_SETIMAGE,
(WPARAM) IMAGE_BITMAP, (LPARAM) hBitmap3);
Sleep(80);
DeleteObject((HBITMAP)hBitmap3);
}
break;
case WM_DESTROY:
DeleteObject((HBITMAP)hBitmap);
DeleteObject((HBITMAP)hBitmap2);
PostQuitMessage(0);
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
void LoadMyImage(void) {
hBitmap = (HBITMAP) LoadImage(NULL, "antvirus.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if(hBitmap == NULL){
MessageBox(NULL, "Error while loading image", "Error", MB_OK|MB_ICONERROR);
}
}
void LoadMyImage2(void) {
hBitmap2 = (HBITMAP) LoadImage(NULL, "botao.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if(hBitmap2 == NULL){
MessageBox(NULL, "Error while loading image", "Error", MB_OK|MB_ICONERROR);
}
}
void LoadMyImage3(void) {
hBitmap3 = (HBITMAP) LoadImage(NULL, "hitmarker.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if(hBitmap3 == NULL){
MessageBox(NULL, "Error while loading image", "Error", MB_OK|MB_ICONERROR);
}
}
我会附上.bmp的:
下面答案中的代码有效,但我希望在按下按钮时打印图像,即Case WM_COMMAND。我仍在尝试编辑它,但谢谢你,你能帮助我真是太好了。
提前致谢。
【问题讨论】:
-
这是试图重塑TransparentBlt。由于您是新手,请务必阅读How to Ask。
-
@LuccaRodrigues 关于如何使用
TransparentBlt(),您到底有什么不明白的地方?它有相当直接的参数。另一种方法是为AlphaBlend()提供一个带有 alpha 通道的 32 位位图,但这需要更多的工作。 -
@LuccaRodrigues 那么您可能没有正确使用它,但我们看不到您尝试了什么。请edit您的问题提供minimal reproducible example。尝试使用位图的其余绘图代码看起来像什么?您无需替换其中的颜色即可使用
TransparentBlt() -
由于
AlphaBlend对您的编译器可见,因此您已经提供了正确的目标版本预处理器符号。作为documented,AlphaBlend是从 Msimg32.lib 导出的,而不是从 Gdi.lib 导出的。您的图像变成了黑白,因为您告诉CreateBitmap 通过将值1传递给nBitCount来创建单色位图。 -
请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange 网络上发帖,您已在 CC BY-SA 4.0 license 下授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work?