首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C++在给定像素数据数组的窗体上绘制矩形

C++在给定像素数据数组的窗体上绘制矩形
EN

Stack Overflow用户
提问于 2019-07-16 00:50:30
回答 1查看 437关注 0票数 2

我将图像数据作为RGB数据的多维数组读入,并希望将其绘制到表单上WM_PAINT中的某个位置。

我知道如何从文件中读取整个位图并将其绘制到某个位置:

代码语言:javascript
复制
    case WM_PAINT:
        PAINTSTRUCT     ps;
        HDC             hdc;
        BITMAP          bitmap;
        HDC             hdcMem;
        HGDIOBJ         oldBitmap;

        hdc = BeginPaint(hwnd, &ps);

        hdcMem = CreateCompatibleDC(hdc);
        oldBitmap = SelectObject(hdcMem, hBitmap);

        GetObject(hBitmap, sizeof(bitmap), &bitmap);
        BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);

        SelectObject(hdcMem, oldBitmap);
        DeleteDC(hdcMem);

        EndPaint(hwnd, &ps);
        break;

而不是如何将特定的像素数据绘制为表单上的位图。我一直在寻找文字上的天数。

感谢您的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-16 02:13:47

基本上,使用CreateDibSection(...)

最小示例用法如下:

代码语言:javascript
复制
#include <windows.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

    MSG msg = { 0 };
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    wc.lpszClassName = L"createdibsection_example";
    if (!RegisterClass(&wc))
        return 1;

    if (!CreateWindow(wc.lpszClassName,
        L"createdibsection example",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0, 0, 640, 480, 0, 0, hInstance, NULL))
        return 2;

    while (GetMessage(&msg, NULL, 0, 0) > 0)
        DispatchMessage(&msg);

    return 0;
}

HBITMAP CreateBitmapAndFillPtrToItsData(unsigned char** ptr_data, int wd, int hgt)
{
    HDC hdcScreen = GetDC(NULL);

    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = wd;
    bmi.bmiHeader.biHeight = -hgt; // top-down
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;

    auto bmp = CreateDIBSection(hdcScreen, &bmi, DIB_RGB_COLORS, (void**) ptr_data, NULL, NULL);

    ReleaseDC(NULL, hdcScreen);
    return bmp;
}

void CopyInPixelData(unsigned char* ptr_data, int wd, int hgt)
{
    // this is just an example for tutorial purposes ... generate a red circle
    // in a white field ... real code would load from a file, etc.

    int c_x = wd / 2;
    int c_y = hgt / 2;
    int radius = c_x;
    int i = 0;
    for (int y = 0; y < hgt; y++) {
        for (int x = 0; x < wd; x++) {
            if ((x-c_x)*(x-c_x) + (y-c_y)*(y-c_y) <= radius*radius) {
                ptr_data[i++] = 0;
                ptr_data[i++] = 0;
                ptr_data[i++] = 255;
                ptr_data[i++] = 0;
            } else {
                ptr_data[i++] = 255;
                ptr_data[i++] = 255;
                ptr_data[i++] = 255;
                ptr_data[i++] = 0;
            }
        }
    }
}

HBITMAP CreateBitmapFromPixelDataExample(int wd, int hgt)
{
    // create a bitmap such that we get a pointer to where its data is stored
    unsigned char* ptr_data;
    auto bitmap = CreateBitmapAndFillPtrToItsData( &ptr_data, wd, hgt );

    // fill in some pixel data...
    CopyInPixelData( ptr_data, wd, hgt );

    return bitmap;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HBITMAP bitmap;

    switch (message)
    {
    case WM_CREATE: {
        bitmap = CreateBitmapFromPixelDataExample(85, 85);
    } break;

    case WM_CLOSE:
        PostQuitMessage(0);
        break;

    case WM_PAINT: {
        RECT r;
        GetClientRect(hWnd, &r);

        auto hdc_bitmap = CreateCompatibleDC(NULL);
        auto hbm_old = (HBITMAP)SelectObject(hdc_bitmap, bitmap);

        PAINTSTRUCT ps;
        auto hdc = BeginPaint(hWnd, &ps);
        // clear bkgd
        FillRect(hdc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));
        // paint in the bitmap we generated from pixel data...
        BitBlt(hdc, 10, 10, 85, 85, hdc_bitmap, 0, 0, SRCCOPY);
        EndPaint(hWnd, &ps);

        SelectObject(hdc_bitmap, hbm_old);
        DeleteDC(hdc_bitmap);

    } break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57044092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档