C 如何分割图像并将其保存在一维数组中
我正在用图像做一个滑动拼图 在这个过程中,我会把这些图像,分成一定大小的瓷砖,然后把它们按顺序排列成一维数组 我将把图像文件注册为资源,或者使用HBITMAP和LoadImage函数导入图像文件 但我想不出我们要如何将这个图像文件分成一定大小(矩形)并存储在一维数组中 是否可以将分割的瓷砖保存到每个图像文件中,然后将文件的路径保存在一维数组中 *注意:必须使用一维数组和双缓冲。您可以这样做 这里有一些简化的代码供您参考C 如何分割图像并将其保存在一维数组中,c,winapi,C,Winapi,我正在用图像做一个滑动拼图 在这个过程中,我会把这些图像,分成一定大小的瓷砖,然后把它们按顺序排列成一维数组 我将把图像文件注册为资源,或者使用HBITMAP和LoadImage函数导入图像文件 但我想不出我们要如何将这个图像文件分成一定大小(矩形)并存储在一维数组中 是否可以将分割的瓷砖保存到每个图像文件中,然后将文件的路径保存在一维数组中 *注意:必须使用一维数组和双缓冲。您可以这样做 这里有一些简化的代码供您参考 int Spilt(HWND hWnd) { BYTE* bitPo
int Spilt(HWND hWnd)
{
BYTE* bitPointer;
HBITMAP g_BitMap = (HBITMAP)LoadImage(NULL, L"C:\\Users\\strives\\Desktop\\timg.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
HDC dc = GetDC(hWnd);
HDC dc_1 = GetDC(hWnd);
HDC hdcMemDC = CreateCompatibleDC(dc);
HDC hdcTemp = CreateCompatibleDC(dc);
HDC hdcMemDC_1 = GetDC(hWnd);
BITMAP bmp;
BITMAP bmp_3;
GetObject(g_BitMap, sizeof(BITMAP), &bmp);
static BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = bmp.bmWidth / 2;
bitmap.bmiHeader.biHeight = bmp.bmHeight;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 24;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = bmp.bmWidth / 2 * bmp.bmHeight * 4;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;
HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
HBITMAP bmp_1 = CreateCompatibleBitmap(hdcMemDC_1, bmp.bmWidth / 2, bmp.bmHeight );
SelectObject(hdcMemDC, g_BitMap);
SelectObject(hdcTemp, bmp_1);
BitBlt(hdcTemp, 0, 0, bmp.bmWidth / 2, bmp.bmHeight, hdcMemDC, 0, 0, SRCCOPY);
GetObject(bmp_1, sizeof(BITMAP), &bmp_3);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmp_3.bmWidth;
bi.biHeight = bmp_3.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmp_3.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmp_3.bmHeight;
// Starting with 24-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
// have greater overhead than HeapAlloc.
HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
GetDIBits(hdcMemDC, bmp_1, 0,
(UINT)bmp_3.bmHeight,
lpbitmap,
(BITMAPINFO *)&bi,
DIB_RGB_COLORS);
// A file is created, this is where we will save the screen capture.
HANDLE hFile = CreateFile(L"spilt_1.bmp",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
bmfHeader.bfSize = dwSizeofDIB;
bmfHeader.bfType = 0x4D42; //BM
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);
//Close the handle for the file that was created
CloseHandle(hFile);
DeleteObject(hdcTemp);
DeleteObject(hdcMemDC);
DeleteObject(hBitmap2);
DeleteObject(bmp_1);
return 0;
}
为了便于理解,我将位图分成两部分,并将它们保存为图像文件。最后,我可以将文件路径保存到一维数组
代码参考:并参考了@Jonathan Potter advice.您不需要将片段序列化为文件。如果你愿意,那是另一个问题
您可以将图像作为一个图像加载,并将其拆分到内存中。基本上为内存中的工件图像创建大小正确的位图,并在每个位图中绘制主位图的一部分。您也不需要通过CreateDIBSection来这样做——只需使用兼容的位图和设备上下文即可
类似于以下内容(我没有对此进行测试)
std::向量拆分位图(HBITMAP bmp,int列,int行)
{
//获取位图尺寸
位图bm;
GetObject(bmp、sizeof(位图)和bm);
int wd=bm.bmWidth,hgt=bm.bmHeight;
int piece_wd=wd/列;
整块_hgt=hgt/行;
//在设备上下文中选择给定位图。
自动hdcScreen=GetDC(NULL);
auto hdcBitmap=CreateCompatibleDC(hdcScreen);
auto-hbmOldBmp=SelectObject(hdcBitmap,bmp);
std::向量片段(列*行);
对于(int row=0;row
向我们展示您的代码、您迄今为止所做的工作创建一个HBITMAP
s数组(例如,对于3x3,您将拥有HBITMAP hbmpTiles[9]
,使用循环初始化数组中的每个HBITMAP
,使用CreateDIBSection
或类似工具,并使用BitBlt
从源位图复制适当的图像数据。不确定是否应使用位图数组。您需要一个数组来保存拼图的逻辑状态。然后,您需要一个可以安德那州。
std::vector<HBITMAP> SplitBitmap(HBITMAP bmp, int columns, int rows)
{
// get the bitmap dimensions
BITMAP bm;
GetObject(bmp, sizeof(BITMAP), &bm);
int wd = bm.bmWidth, hgt = bm.bmHeight;
int piece_wd = wd / columns;
int piece_hgt = hgt / rows;
// Select the given bitmap into a device context.
auto hdcScreen = GetDC(NULL);
auto hdcBitmap = CreateCompatibleDC(hdcScreen);
auto hbmOldBmp = SelectObject(hdcBitmap, bmp);
std::vector<HBITMAP> pieces(columns*rows);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < columns; col++) {
// create a device context for a piece and select an appropriately sized bitmap into it
auto hdcPiece = CreateCompatibleDC(hdcScreen);
auto hbmPiece = CreateCompatibleBitmap(hdcScreen, piece_wd, piece_hgt);
auto hbmOldPiece = SelectObject(hdcPiece, hbmPiece);
// paint a piece of the whole bitmap into the piece bitmap
BitBlt(hdcPiece, 0, 0, piece_wd, piece_hgt, hdcBitmap, col * piece_wd, row * piece_hgt, SRCCOPY);
// cleanup per piece resources we dont need.
SelectObject(hdcPiece, hbmOldPiece);
DeleteDC(hdcPiece);
pieces[row * columns + col] = hbmPiece;
}
}
SelectObject(hdcBitmap, hbmOldBmp);
DeleteDC(hdcBitmap);
ReleaseDC(NULL, hdcScreen);
return pieces;
}
...
auto hbm = (HBITMAP)LoadImage(NULL, L"C:\\work\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
auto pieces = SplitBitmap(hbm, 4, 4);