【问题标题】:Set bitmap background the same pixels as the bitmap behind it - Windows API将位图背景设置为与其背后的位图相同的像素 - Windows API
【发布时间】: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的:

hitmarker.bmp

antvirus.bmp

botao.bmp

下面答案中的代码有效,但我希望在按下按钮时打印图像,即Case WM_COMMAND。我仍在尝试编辑它,但谢谢你,你能帮助我真是太好了。 提前致谢。

【问题讨论】:

  • 这是试图重塑TransparentBlt。由于您是新手,请务必阅读How to Ask
  • @LuccaRodrigues 关于如何使用TransparentBlt(),您到底有什么不明白的地方?它有相当直接的参数。另一种方法是为AlphaBlend() 提供一个带有 alpha 通道的 32 位位图,但这需要更多的工作。
  • @LuccaRodrigues 那么您可能没有正确使用它,但我们看不到您尝试了什么。请edit您的问题提供minimal reproducible example。尝试使用位图的其余绘图代码看起来像什么?您无需替换其中的颜色即可使用TransparentBlt()
  • 由于AlphaBlend 对您的编译器可见,因此您已经提供了正确的目标版本预处理器符号。作为documentedAlphaBlend 是从 Msimg32.lib 导出的,而不是从 Gdi.lib 导出的。您的图像变成了黑白,因为您告诉CreateBitmap 通过将值1 传递给nBitCount 来创建单色位图。
  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange 网络上发帖,您已在 CC BY-SA 4.0 license 下授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work?

标签: c windows api winapi bmp


【解决方案1】:

cmets已经给出了足够详细的信息,你只需使用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);
    }

}

调试:

【讨论】:

  • 请注意,每次调用WM_PAINT 时都加载图像不是一个好主意。它们应该加载一次,例如在WM_CREATE 中,然后在每次调用WM_PAINT 时使用,然后卸载一次,例如在WM_DESTROY 中。
  • @Lucca Rodrigues 嗨,如果答案有帮助,您可以随时 accept 它。
猜你喜欢
  • 1970-01-01
  • 2013-10-28
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多