繁体   English   中英

C++ - 创建 bmp 文件并通过 createwindow() 显示时出现问题

[英]C++ - Problem with create bmp file and show it by createwindow()

我有一个 function 获取数据并将.BMP 文件创建为二维码。

    int CreateBmpFile(std::wstring barcode)
{
    const std::string data(barcode.begin(), barcode.end());
    //const char* data;
    char* szSourceSring = (char*)data.c_str();
    unsigned int    unWidth, x, y, l, n, unWidthAdjusted, unDataBytes;
    unsigned char* pRGBData, * pSourceData, * pDestData;
    QRcode* pQRC;
    FILE* f;

    // Compute QRCode

    if (pQRC = QRcode_encodeString(szSourceSring, 0, QR_ECLEVEL_L, QR_MODE_8, 1))
        //if(pQRC=QRcode_encodeString8bit(szSourceSring,0,QR_ECLEVEL_L))
    {
        unWidth = pQRC->width;
        unWidthAdjusted = unWidth * OUT_FILE_PIXEL_PRESCALER * 3;
        if (unWidthAdjusted % 4)
            unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4;
        unDataBytes = unWidthAdjusted * unWidth * OUT_FILE_PIXEL_PRESCALER;

        // Allocate pixels buffer

        if (!(pRGBData = (unsigned char*)malloc(unDataBytes)))
        {
            printf("Out of memory");
            exit(-1);
        }

        // Preset to white

        memset(pRGBData, 0xff, unDataBytes);


        // Prepare bmp headers

        BITMAPFILEHEADER kFileHeader;
        kFileHeader.bfType = 0x4d42;  // "BM"
        kFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + unDataBytes;
        kFileHeader.bfReserved1 = 0;
        kFileHeader.bfReserved2 = 0;
        kFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) +          sizeof(BITMAPINFOHEADER);

        BITMAPINFOHEADER kInfoHeader;
        kInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
        kInfoHeader.biWidth = unWidth * OUT_FILE_PIXEL_PRESCALER;
        kInfoHeader.biHeight = -((int)unWidth * OUT_FILE_PIXEL_PRESCALER);
        kInfoHeader.biPlanes = 1;
        kInfoHeader.biBitCount = 24;
        kInfoHeader.biCompression = BI_RGB;
        kInfoHeader.biSizeImage = 0;
        kInfoHeader.biXPelsPerMeter = 0;
        kInfoHeader.biYPelsPerMeter = 0;
        kInfoHeader.biClrUsed = 0;
        kInfoHeader.biClrImportant = 0;


        // Convert QrCode bits to bmp pixels

        pSourceData = pQRC->data;
        for (y = 0; y < unWidth; y++)
        {
            pDestData = pRGBData + unWidthAdjusted * y * OUT_FILE_PIXEL_PRESCALER;
            for (x = 0; x < unWidth; x++)
            {
                if (*pSourceData & 1)
                {
                    for (l = 0; l < OUT_FILE_PIXEL_PRESCALER; l++)
                    {
                        for (n = 0; n < OUT_FILE_PIXEL_PRESCALER; n++)
                        {
                            *(pDestData + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_B;
                            *(pDestData + 1 + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_G;
                            *(pDestData + 2 + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_R;
                        }
                    }
                }
                pDestData += 3 * OUT_FILE_PIXEL_PRESCALER;
                pSourceData++;
            }
        }


        // Output the bmp file

        if (!(fopen_s(&f, OUT_FILE, "wb")))
        {
            fwrite(&kFileHeader, sizeof(BITMAPFILEHEADER), 1, f);
            fwrite(&kInfoHeader, sizeof(BITMAPINFOHEADER), 1, f);
            fwrite(pRGBData, sizeof(unsigned char), unDataBytes, f);

            fclose(f);
        }
        else
        {
            printf("Unable to open file");
            exit(-1);
        }

        // Free data

        free(pRGBData);
        QRcode_free(pQRC);
    }
    else
    {
        printf("NULL returned");
        exit(-1);
    }
    return 0;
}

调用此 function 后,我的 bmp 文件创建,我可以在 windows 中打开它以显示。

如果我想加载它并通过以下代码在我的 win32 对话框中显示:

HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, L"samanqrcode.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_SHARED);
    DWORD err = GetLastError();
    WCHAR szTest[10]; 
    swprintf_s(szTest, 10, L"%d", err);
    if(hBitmap == NULL)
        ::MessageBox(_hWnd, szTest, L"rrrrrrr", 0);


    if (SUCCEEDED(hr))
    {
        _Image_Barcode = ::CreateWindow(_T("STATIC"), _T(""),
            WS_CHILD | WS_VISIBLE | SS_BITMAP,
            85, 70, 230, 230,
            _hWnd,
            (HMENU)IDI_BARCODE_IMAGE,
            _hinst,
            NULL);
        if (_Image_Barcode == NULL)
            hr = HRESULT_FROM_WIN32(::GetLastError());
    }

    ::SendMessage(_Image_Barcode, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);

LoadImage function 返回 NULL 并且错误代码为 0。

如果我在 LoadImage function 中使用其他文件名(例如由绘图应用程序在 windows 或其他...中创建的任何 bmp 文件),bmp 文件将正确显示。

我创建 bmp 文件的方法不正确吗?

编辑:

这个问题就像我的问题。 带有 QRCode bitmap 的 LoadImage() 失败,除非先使用 MS Paint 打开/保存文件

评论中的该用户说:@AbhilashAruva 嗨,感谢您的回复。 我对 c++ 中的这些图像非常陌生。 我找到了解决此问题的解决方法。 我正在从我的库中生成 JPEG 格式的图像,然后使用 gdi+ 将此图像转换为 bmp 格式。 loadImage function 现在能够加载新的 bmp 图像。 感谢所有的帮助。 – Abhilash Aruva 2014 年 10 月 8 日在 7:40

他是我的什么? 我无法实现他的方法。

我找到解决方案。 使用 from gdi+ 将 bmp 转换为 jpg 并将 jpg 转换为 bmp。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM