简体   繁体   中英

Set bitmap background the same pixels as the bitmap behind it - Windows API

I was trying to print a.bmp when I pressed a button, but this image would have to have "transparency".

I thought about changing the color of each pixel. This.bmp would be in front of another one, so what I want to do is: take the color of the pixels from the.bmp behind and paint the background of the front one with them .

The problem:

I imagine this could be done, considering that the background of the.bmp is white, just identifying if a pixel is white and changing its color.

However, I was not successful in trying to do this... I tried several references to base myself, none of them worked.

I tried this one : I tried to edit it to change the background pixels of the.bmp when they are white, to the pixels of the.bmp behind it. I was not successful, the pixels were all scrambled.

I also tried this one : the image was black and white (this has already been explained in the comments below).

I haven't find an example of the TransparentBlt() function usage with bitmaps to base myself on, I already tried to use it, but the image remained the same. here's my whole code:

#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);
    }
}

I will attach the.bmp's:

hitmarker.bmp

antvirus.bmp

botao.bmp

The code in the answer below works, but I wanted the image to be printed when the button was pressed, that is, Case WM_COMMAND . I'm still trying to edit it, but thank you, it's very kind of you to help me. Thanks in advance.

The comments have given enough detailed information, all you have to do is use TransparentBlt .

Minimal code example:

#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);
    }

}

Debug:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM