c++ - 如何增加位图像素大小?
问题描述
我正在努力寻找增加 win32 位图中像素大小的方法。有什么办法吗?
我在下面做了一个小的win32程序。当你运行它时,你应该得到一个窗口,中间有一个非常小的红点。您可以使用向上、向下、向左和向右箭头键来控制圆点。
/* compile: gcc test.c -o test -lgdi32 -Wl,-subsystem,windows */
// TODO fast way to update? resize pixel size? best coding practices?
#include <windows.h>
#define WND_WIDTH 500
#define WND_HEIGHT 500
#define ID_TIMER 1
void DrawBitmap(HDC hdc, RECT *rect, BITMAPINFO info, void *bmpMem)
{
int width = rect->right - rect->left;
int height = rect->bottom - rect->top;
StretchDIBits(hdc,
0,
0,
info.bmiHeader.biWidth,
info.bmiHeader.biHeight,
0,
0,
width,
height,
bmpMem,
&info,
DIB_RGB_COLORS,
SRCCOPY);
}
void UpdateBitmap(BITMAPINFO info, void *bmpMem, POINT pix)
{
int width = info.bmiHeader.biWidth;
int height = info.bmiHeader.biHeight;
BYTE *pixel = (BYTE *) bmpMem;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (x == pix.x && y == pix.y)
{
*pixel++ = 0; /* blue */
*pixel++ = 0; /* green */
*pixel++ = 255; /* red */
*pixel++ = 255; /* alpha */
}
else
{
*pixel++ = 0; /* blue */
*pixel++ = 0; /* green */
*pixel++ = 0; /* red */
*pixel++ = 255; /* alpha */
}
}
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static BITMAPINFO info;
static void *bmpMem;
static POINT pixel;
switch (msg)
{
case WM_CREATE:
{
RECT rcClient;
GetClientRect(hWnd, &rcClient);
int width = rcClient.right - rcClient.left;
int height = rcClient.bottom - rcClient.top;
info.bmiHeader.biSize = sizeof(info.bmiHeader);
info.bmiHeader.biWidth = width;
info.bmiHeader.biHeight = height;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biCompression = BI_RGB;
info.bmiHeader.biSizeImage = 0;
info.bmiHeader.biXPelsPerMeter = 0;
info.bmiHeader.biYPelsPerMeter = 0;
info.bmiHeader.biClrUsed = 0;
info.bmiHeader.biClrImportant = 0;
bmpMem = VirtualAlloc(0, width * height * 4, MEM_COMMIT, PAGE_READWRITE);
pixel.x = width / 2;
pixel.y = height / 2;
if(!SetTimer(hWnd, ID_TIMER, 50, NULL))
{
MessageBox(hWnd, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
PostQuitMessage(1);
}
break;
}/*
case WM_PAINT:
{
RECT rcClient;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rcClient);
DrawBitmap(hdc, &rcClient, info, bmpMem);
EndPaint(hWnd, &ps);
break;
}*/
case WM_TIMER:
{
RECT rcClient;
HDC hdc = GetDC(hWnd);
GetClientRect(hWnd, &rcClient);
UpdateBitmap(info, bmpMem, pixel);
DrawBitmap(hdc, &rcClient, info, bmpMem);
ReleaseDC(hWnd, hdc);
break;
}
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_LEFT: pixel.x -= 1; break;
case VK_RIGHT: pixel.x += 1; break;
case VK_UP: pixel.y += 1; break;
case VK_DOWN: pixel.y -= 1; break;
}
break;
}
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
KillTimer(hWnd, ID_TIMER);
VirtualFree(bmpMem, 0, MEM_RELEASE);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
const TCHAR szClassName[] = TEXT("MyClass");
WNDCLASS wc;
HWND hWnd;
MSG msg;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClass(&wc))
{
MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error!"),
MB_ICONEXCLAMATION | MB_OK);
return 1;
}
hWnd = CreateWindow(szClassName,
TEXT("Title"),
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, /* this window style prevents window resizing */
CW_USEDEFAULT,
CW_USEDEFAULT,
WND_WIDTH,
WND_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
if (hWnd == NULL)
{
MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"),
MB_ICONEXCLAMATION | MB_OK);
return 1;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
我想增加位图中小红点和所有其他像素的大小。我试图像这样减小宽度和高度
switch (msg)
{
case WM_CREATE:
{
//RECT rcClient;
//GetClientRect(hWnd, &rcClient);
int width = 30;
int height = 30;
我希望在中心看到一个大红点,但我得到了白屏。如何编辑代码以显示更大的像素?
解决方案
您正在 UpdateBitmap 中创建单个红色像素:
if (x == pix.x && y == pix.y)
{
*pixel++ = 0; /* blue */
*pixel++ = 0; /* green */
*pixel++ = 255; /* red */
*pixel++ = 255; /* alpha */
}
如果你想要一个更大的“点” - 在某处定义一个半径:
int r = 17;
并将您的条件更改为
if ((x - pix.x)* (x - pix.x) + (y - pix.y)* (y - pix.y) <= r*r)
要缩放整个位图,请修改DrawBitmap
:
void DrawBitmap(HDC hdc, RECT* rect, BITMAPINFO info, void* bmpMem)
{
int width = rect->right - rect->left;
int height = rect->bottom - rect->top;
int scale = 7;
StretchDIBits(hdc,
-(info.bmiHeader.biWidth * scale - width) / 2,
-(info.bmiHeader.biHeight * scale - height) / 2,
info.bmiHeader.biWidth * scale,
info.bmiHeader.biHeight * scale,
0,
0,
width,
height,
bmpMem,
&info,
DIB_RGB_COLORS,
SRCCOPY);
}
StretchDIBits
将源区域(由 指定)拉伸(或缩小)0, 0, width, height
到目标区域。在这个例子中,我将目的地的大小放大了scale
- 所以图像会被拉伸。负偏移量是将图像“居中”在目标上;你可以0,0
用来保持左上角的锚点。
推荐阅读
- python - 如何正确使用Integrate.cumtrapz?
- binding - 将 SwiftUI 视图绑定到领域对象的意外行为
- python - 有没有办法在 Python 中进行 raking?
- php - 在图片下方显示产品简短描述
- iframe - 添加框架祖先/没有错误/但仍然无法显示 iframe
- c++ - 在堆栈上创建类实例
- javascript - 使用 jQuery 更改单击按钮的外观,并覆盖 btn-warning 类
- java - 如果未播放媒体播放器,应用程序退出时应用程序崩溃
- python - 如何在哈里斯角检测算法中实现计数器?
- tensorflow - 如何将数据提供给正在连接的 NN 模型?