将位图背景设置为与其背后的位图相同的像素 - Windows API
Set bitmap background the same pixels as the bitmap behind it - Windows API
我试图在按下按钮时打印 .bmp,但此图像必须具有“透明度”。
我想过改变每个像素的颜色。这个 .bmp 会在另一个之前,所以我想做的是:从后面的 .bmp 中获取像素的颜色并用它们绘制前面的背景 .
问题:
我想这是可以做到的,考虑到 .bmp 的背景是白色的,只需识别像素是否为白色并更改其颜色即可。
但是,我尝试这样做没有成功...
我尝试了几个参考资料作为自己的基础,none 其中有效。
我尝试了 this one:我尝试编辑它以将 .bmp 为白色时的背景像素更改为它后面的 .bmp 的像素。 我没有成功,像素都乱码了
我也试过this one:图像是黑白的(这已经在下面的评论中解释过了)。
我还没有找到 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 文件:
hitmarker.bmp
antvirus.bmp
botao.bmp
下面答案中的代码有效,但我希望在按下按钮时打印图像,即 Case WM_COMMAND
。我仍在尝试编辑它,但谢谢你,你帮我真是太好了。
提前致谢。
评论已经提供了足够详细的信息,您只需使用TransparentBlt。
最小代码示例:
#include <Windows.h>
#pragma comment(lib,"Msimg32.lib")
using namespace std;
HBITMAP hBitmap;
HBITMAP hBitmap3;
void LoadMyImage(void) {
hBitmap = (HBITMAP)LoadImage(NULL, L"C:\Users\xx\Desktop\PGUfb.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hBitmap == NULL) {
MessageBox(NULL, L"Error while loading image", L"Error", MB_OK | MB_ICONERROR);
}
}
void LoadMyImage3(void) {
hBitmap3 = (HBITMAP)LoadImage(NULL, L"C:\Users\xx\Desktop\QZLMJ.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hBitmap3 == NULL) {
MessageBox(NULL, L"Error while loading image", L"Error", MB_OK | MB_ICONERROR);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC memdc;
HDC dcSkin;
HBITMAP hOldMemBmp;
HBITMAP hOldSkinBmp;
switch (message)
{
case WM_CREATE:
{
LoadMyImage();
LoadMyImage3();
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// TODO: Add any drawing code that uses hdc here...
memdc = CreateCompatibleDC(hdc);
dcSkin = CreateCompatibleDC(hdc);
hOldMemBmp = (HBITMAP)SelectObject(memdc, hBitmap);
hOldSkinBmp = (HBITMAP)SelectObject(dcSkin, hBitmap3);
TransparentBlt(memdc, 200, 100, 38,38, dcSkin, 0, 0, 38, 38, RGB(255, 255, 255));
BitBlt(hdc, 0, 0, 988, 562, memdc, 0, 0, SRCCOPY);
DeleteObject(hOldSkinBmp);
DeleteObject(hOldMemBmp);
DeleteDC(memdc);
DeleteDC(dcSkin);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
DeleteObject(hBitmap);
DeleteObject(hBitmap3);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
};
HINSTANCE hinst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
HWND hwnd;
hinst = GetModuleHandle(NULL);
// create a window class:
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = L"win32";
// register class with operating system:
RegisterClass(&wc);
// create and show window:
hwnd = CreateWindow(L"win32", L"My program", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 0, 0, 1000, 800, NULL, NULL, hinst, NULL);
if (hwnd == NULL) {
return 0;
}
ShowWindow(hwnd, SW_SHOW);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
调试:
我试图在按下按钮时打印 .bmp,但此图像必须具有“透明度”。
我想过改变每个像素的颜色。这个 .bmp 会在另一个之前,所以我想做的是:从后面的 .bmp 中获取像素的颜色并用它们绘制前面的背景 .
问题:
我想这是可以做到的,考虑到 .bmp 的背景是白色的,只需识别像素是否为白色并更改其颜色即可。
但是,我尝试这样做没有成功... 我尝试了几个参考资料作为自己的基础,none 其中有效。
我尝试了 this one:我尝试编辑它以将 .bmp 为白色时的背景像素更改为它后面的 .bmp 的像素。 我没有成功,像素都乱码了
我也试过this one:图像是黑白的(这已经在下面的评论中解释过了)。
我还没有找到 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 文件:
hitmarker.bmp
antvirus.bmp
botao.bmp
下面答案中的代码有效,但我希望在按下按钮时打印图像,即 Case WM_COMMAND
。我仍在尝试编辑它,但谢谢你,你帮我真是太好了。
提前致谢。
评论已经提供了足够详细的信息,您只需使用TransparentBlt。
最小代码示例:
#include <Windows.h>
#pragma comment(lib,"Msimg32.lib")
using namespace std;
HBITMAP hBitmap;
HBITMAP hBitmap3;
void LoadMyImage(void) {
hBitmap = (HBITMAP)LoadImage(NULL, L"C:\Users\xx\Desktop\PGUfb.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hBitmap == NULL) {
MessageBox(NULL, L"Error while loading image", L"Error", MB_OK | MB_ICONERROR);
}
}
void LoadMyImage3(void) {
hBitmap3 = (HBITMAP)LoadImage(NULL, L"C:\Users\xx\Desktop\QZLMJ.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hBitmap3 == NULL) {
MessageBox(NULL, L"Error while loading image", L"Error", MB_OK | MB_ICONERROR);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC memdc;
HDC dcSkin;
HBITMAP hOldMemBmp;
HBITMAP hOldSkinBmp;
switch (message)
{
case WM_CREATE:
{
LoadMyImage();
LoadMyImage3();
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// TODO: Add any drawing code that uses hdc here...
memdc = CreateCompatibleDC(hdc);
dcSkin = CreateCompatibleDC(hdc);
hOldMemBmp = (HBITMAP)SelectObject(memdc, hBitmap);
hOldSkinBmp = (HBITMAP)SelectObject(dcSkin, hBitmap3);
TransparentBlt(memdc, 200, 100, 38,38, dcSkin, 0, 0, 38, 38, RGB(255, 255, 255));
BitBlt(hdc, 0, 0, 988, 562, memdc, 0, 0, SRCCOPY);
DeleteObject(hOldSkinBmp);
DeleteObject(hOldMemBmp);
DeleteDC(memdc);
DeleteDC(dcSkin);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
DeleteObject(hBitmap);
DeleteObject(hBitmap3);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
};
HINSTANCE hinst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
HWND hwnd;
hinst = GetModuleHandle(NULL);
// create a window class:
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = L"win32";
// register class with operating system:
RegisterClass(&wc);
// create and show window:
hwnd = CreateWindow(L"win32", L"My program", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 0, 0, 1000, 800, NULL, NULL, hinst, NULL);
if (hwnd == NULL) {
return 0;
}
ShowWindow(hwnd, SW_SHOW);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
调试: