保存位图

时间:2013-09-03 22:45:05

标签: c++ winapi bitmap

我正在学习有关保存位图的教程。它进展顺利,但我现在遇到了问题。该程序确实成功编译。它可以保存文件,但是当我打开文件时它会显示:

Windows Live照片库:

  

照片库无法打开此照片或视频。该文件可能是   没有支持,损坏或腐败。

以下是一些代码: 调用WndProc()中的函数:

case SAVE_BM:
{
    BOOL result = SaveFileDlg(hwnd, filePath, "Save Bitmap");
    if (result)
    {
        PBITMAPINFO pbi = CreateBmpInfoStruct(hwnd, hBitmap);
        hdc = GetDC(hwnd);
        SaveBmpFile(hwnd, filePath, pbi, hBitmap, hdc);
    }
    return 0;
}

SaveBmpFile():

void SaveBmpFile(HWND hwnd, LPSTR file, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC)
{
    std::ofstream hF;
    BITMAPFILEHEADER bmfh;
    PBITMAPINFOHEADER pbmih;
    LPBYTE bits;
    DWORD total;
    DWORD cB;
    BYTE *hP;
    pbmih = (PBITMAPINFOHEADER) pbi;
    bits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbmih->biSizeImage);
    if (!bits)
        MessageBox(hwnd, "GlobalAlloc()", "Error", MB_OK);
    if (!GetDIBits(hDC, hBMP, 0, (WORD) pbmih->biHeight, bits, pbi, DIB_RGB_COLORS))
        MessageBox(hwnd, "GetDIBits()", "Error", MB_OK);
    hF.open(file, std::ios::binary);
    if (hF.fail())
        MessageBox(hwnd, "open()", "Error", MB_OK);
    bmfh.bfType = 0x4d42;
    bmfh.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbmih->biSize + pbmih->biClrUsed * sizeof(RGBQUAD) + pbmih->biSizeImage);
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbmih->biSize + pbmih->biClrUsed * sizeof(RGBQUAD);
    hF.write((char*) &bmfh, sizeof(BITMAPFILEHEADER));
    if (hF.fail())
        MessageBox(hwnd, "write() file header", "Error", MB_OK);
    hF.write((char*) pbmih, sizeof(BITMAPINFOHEADER) + pbmih->biClrUsed * sizeof(RGBQUAD));
    if (hF.fail())
        MessageBox(hwnd, "write() info header", "Error", MB_OK);
    total = cB = pbmih->biSizeImage;
    hP = bits;
    hF.write((char*) hP, (int) cB);
    if (hF.fail())
        MessageBox(hwnd, "write() data", "Error", MB_OK);
    hF.close();
    if (hF.fail())
        MessageBox(hwnd, "close()", "Error", MB_OK);
    GlobalFree((HGLOBAL) bits);
}

SaveBmpInfoStruct():

PBITMAPINFO CreateBmpInfoStruct(HWND hwnd, HBITMAP hBMP)
{
    BITMAP BMP;
    PBITMAPINFO pbmi;
    WORD clrBits;
    if (!GetObject(hBMP, sizeof(BITMAP), (LPSTR) &BMP))
        MessageBox(hwnd, "GetObject()", "Error", MB_OK);
    clrBits = (WORD) (BMP.bmPlanes * BMP.bmBitsPixel);
    if (clrBits == 1)
        clrBits = 1;
    else if (clrBits <= 4)
        clrBits = 4;
    else if (clrBits <= 8)
        clrBits = 8;
    else if (clrBits <= 16)
        clrBits = 16;
    else if (clrBits <= 24)
        clrBits = 24;
    else
        clrBits = 32;
    if (clrBits != 24)
        pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< clrBits));
    else
        pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pbmi->bmiHeader.biWidth = BMP.bmWidth;
    pbmi->bmiHeader.biHeight = BMP.bmHeight;
    pbmi->bmiHeader.biPlanes = BMP.bmPlanes;
    pbmi->bmiHeader.biBitCount = BMP.bmBitsPixel;
    if (clrBits < 24)
        pbmi->bmiHeader.biClrUsed = (1<< clrBits);
    pbmi->bmiHeader.biCompression = BI_RGB;
    pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * clrBits + 31) & ~31) / 8 * pbmi->bmiHeader.biHeight;
    pbmi->bmiHeader.biClrImportant = 0;
    return pbmi;
    }

SaveFileDlg():

BOOL SaveFileDlg(HWND hwnd, LPSTR fileName, LPSTR titleName)
{
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hInstance = GetModuleHandle(NULL);
    ofn.lpstrCustomFilter = NULL;
    ofn.nMaxCustFilter = 0;
    ofn.nFilterIndex = 0;
    ofn.hwndOwner = hwnd;
    ofn.lpstrFile = fileName;
    ofn.lpstrFileTitle = NULL;
    ofn.lpstrTitle = titleName;
    ofn.Flags = OFN_EXPLORER | OFN_OVERWRITEPROMPT;
    ofn.lpstrFilter = "Bitmap Files (*.bmp)\0*.bmp\0\0";
    ofn.lpstrTitle = titleName;
    return GetSaveFileName(&ofn);
}

如果您需要查看更多代码,请告诉我们。 我曾几次搜索谷歌,但我没有找到任何东西。在这种情况下找到一些东西有点困难。我在另一个论坛上尝试了这个,但它没有成功,正如你可以告诉我的那样。

感谢您的帮助!

0 个答案:

没有答案