Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何分割图像并将其保存在一维数组中_C_Winapi - Fatal编程技术网

C 如何分割图像并将其保存在一维数组中

C 如何分割图像并将其保存在一维数组中,c,winapi,C,Winapi,我正在用图像做一个滑动拼图 在这个过程中,我会把这些图像,分成一定大小的瓷砖,然后把它们按顺序排列成一维数组 我将把图像文件注册为资源,或者使用HBITMAP和LoadImage函数导入图像文件 但我想不出我们要如何将这个图像文件分成一定大小(矩形)并存储在一维数组中 是否可以将分割的瓷砖保存到每个图像文件中,然后将文件的路径保存在一维数组中 *注意:必须使用一维数组和双缓冲。您可以这样做 这里有一些简化的代码供您参考 int Spilt(HWND hWnd) { BYTE* bitPo

我正在用图像做一个滑动拼图

在这个过程中,我会把这些图像,分成一定大小的瓷砖,然后把它们按顺序排列成一维数组

我将把图像文件注册为资源,或者使用HBITMAP和LoadImage函数导入图像文件

但我想不出我们要如何将这个图像文件分成一定大小(矩形)并存储在一维数组中

是否可以将分割的瓷砖保存到每个图像文件中,然后将文件的路径保存在一维数组中

*注意:必须使用一维数组和双缓冲。

您可以这样做

这里有一些简化的代码供您参考

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