C++ C++;在给定的像素数据数组上绘制矩形
我将图像数据作为RGB数据的多维数组读取,并希望在WM_PAINT中的某个位置将其绘制在窗体上 我知道如何从文件中读取整个位图并在某个位置绘制:C++ C++;在给定的像素数据数组上绘制矩形,c++,winapi,C++,Winapi,我将图像数据作为RGB数据的多维数组读取,并希望在WM_PAINT中的某个位置将其绘制在窗体上 我知道如何从文件中读取整个位图并在某个位置绘制: case WM_PAINT: PAINTSTRUCT ps; HDC hdc; BITMAP bitmap; HDC hdcMem; HGDIOBJ oldBitmap;
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;
但不是如何将特定像素数据作为位图显示在窗体上。我已经找了好几天了
感谢您的帮助。基本上,请使用
以下是最低限度的示例用法:
#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;
}
#包括
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM);
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE HPPreInstance、LPSTR lpCmdLine、int nCmdShow)
{
MSG={0};
WNDCLASS wc={0};
wc.lpfnWndProc=WndProc;
wc.hInstance=hInstance;
wc.hbrBackground=(HBRUSH)(彩色背景);
wc.lpszClassName=L“createdibsection_示例”;
如果(!注册表类(&wc))
返回1;
如果(!CreateWindow(wc.lpszClassName,
L“createdibsection示例”,
WS|U重叠窗口| WS|U可见,
0,0,640,480,0,0,hInstance,NULL)
返回2;
while(GetMessage(&msg,NULL,0,0)>0)
发送消息(&msg);
返回0;
}
HBITMAP CreateBitmapAndFillPtrToItsData(无符号字符**ptr_数据,整数wd,整数hgt)
{
HDC hdcScreen=GetDC(NULL);
BITMAPINFO bmi;
memset(&bmi,0,sizeof(BITMAPINFO));
bmi.bmiHeader.biSize=sizeof(BitMapInfo头文件);
bmi.bmiHeader.biWidth=wd;
bmi.bmiHeader.biHeight=-hgt;//自上而下
bmi.bmiHeader.biPlanes=1;
bmi.bmiHeader.biBitCount=32;
bmi.bmiHeader.biCompression=BI_RGB;
自动bmp=CreateDIBSection(hdcScreen,&bmi,DIB_RGB_颜色,(void**)ptr_数据,NULL,NULL);
ReleaseDC(空,hdcScreen);
返回bmp;
}
无效CopyInPixelData(无符号字符*ptr_数据,整数wd,整数hgt)
{
//这只是一个用于教程目的的示例…生成一个红色圆圈
//在白色字段中…实际代码将从文件加载,等等。
int c_x=wd/2;
国际货币基金组织=hgt/2;
int半径=c_x;
int i=0;
对于(int y=0;y 如果((x-c_x)*(x-c_x)+(y-c_y)*(y-c_y)从像素数据创建位图。查看函数,如CreateDibSection()
,CreateDIBitmap()
,SetDIBits()
,setDibitToDevice()
,等等。然后像通常一样将位图绘制到表单上。谢谢,按照它所采用的格式,如何在ptr_数据中设置特定的x,y rgb点?像素格式取决于在BitMapinFoHeader结构中传递的biCompression和biBitCount值。我刚刚更新了上面的代码,以便更宽容。当你传递BI时_RGB作为双压缩,你说的是tou将只列出RGB值,然后biBitCount表示每个像素有多少位,通常是24位或32位,即每个像素有三个字节,alpha是否有一个字节。数据是逐行排列的,必须是DWORD对齐的。如果你设置了每个像素32位,就像我现在看到的那样,你不需要e担心填充行/对齐。