2014-01-21 40 views
0

的陣列8位位圖,我想確保我的位圖的理解是正確的,並得到一些幫助察覺的錯誤。基本上我想要做的是保存一個8位位圖文件,同時將其顯示在MFC應用程序的圖片框中。我想避免保存位圖的繁瑣方法,然後重新加載它。創建從這個已被竊聽了我一段時間的數字

的文件保存操作主要是成功的,但是我改變了我的代碼,現在曾經被認爲是在文件中白(在這種情況下它的黑白圖像)現身通常爲綠色,但它的變化。我猜這是因爲我的數據可能引用了顏色表中的信息,哪個值是白色的?

HBITMAP ReadWrite::SaveFile(LPCTSTR file, double* data) { 

    BYTE* bmp = ConvertData(data); 
    HANDLE hf; 
    BITMAPINFO* pbmi = WriteHeader(file); 

    BITMAPFILEHEADER* bmfh = (BITMAPFILEHEADER*)alloca(sizeof(BITMAPFILEHEADER)); 
    bmfh->bfType = 0x4d42; // 'BM' 
    bmfh->bfReserved1 = 0; 
    bmfh->bfReserved2 = 0; 
    bmfh->bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbmi->bmiHeader.biSize + 256 * sizeof(RGBQUAD); 
    bmfh->bfSize = (DWORD)(bmfh->bfOffBits + pbmi->bmiHeader.biSizeImage); 


    hf = CreateFile(file, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, 
     NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); 

    if (hf == NULL) // error creating 
    { 
     CloseHandle (hf); 
     return NULL; 
    } 

    // write header 
    unsigned long bwritten; 
    if (!WriteFile(hf, (LPCVOID)bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL)) 
    { 
     CloseHandle (hf); 
     return NULL; 
    } 

    // write infoheader 
    if (!WriteFile(hf, (LPCVOID)pbmi, sizeof (BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), &bwritten, NULL)) 
    { 
     CloseHandle (hf); 
     return NULL; 
    } 

    // write image data 
    if (!WriteFile(hf, (LPCVOID)bmp_data, (int) pbmi->bmiHeader.biSizeImage, &bwritten, NULL)) 
    { 
     CloseHandle (hf); 
     return NULL; 
    } 

    // Close 
    CloseHandle(hf); 

    // Send back a file to display 
    return CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void**)bmp_data, NULL, 0); 
} 

代碼寫入infoheader +調色板(這應該是值範圍從黑到白??)

BITMAPINFO* ReadWrite::WriteHeader(LPCTSTR fn) 
{ 
    int R = ReadWrite::getR(); 
    int C = ReadWrite::getC(); 

    BITMAPINFO* pbmi = (BITMAPINFO*)alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256); 
    pbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); 
    pbmi->bmiHeader.biWidth = R; 
    pbmi->bmiHeader.biHeight = -C; 
    pbmi->bmiHeader.biPlanes = 1; 
    pbmi->bmiHeader.biBitCount = 8; 
    pbmi->bmiHeader.biCompression = BI_RGB; 
    pbmi->bmiHeader.biSizeImage = (((R * pbmi->bmiHeader.biBitCount + 31) & ~31) >> 3) * C; 
    pbmi->bmiHeader.biClrUsed = 256; 
    pbmi->bmiHeader.biClrImportant = 0; 
    for(int i=0; i<256; i++) 
    { 
     pbmi->bmiColors[i].rgbRed = i; 
     pbmi->bmiColors[i].rgbGreen = i; 
     pbmi->bmiColors[i].rgbBlue = i; 
     pbmi->bmiColors[i].rgbReserved = 0; 
    } 

    //return true; 
    return pbmi; 
} 

最後轉換我的號碼陣列分爲無符號字符「字節」:

BYTE* ReadWrite::ConvertData(double* data) { 

    BYTE* bmp_data; 
    int R = ReadWrite::getR(); 
    int C = ReadWrite::getC(); 
    bool binary = ReadWrite::getBinary(); 

    bmp_data = new BYTE [R*C]; 

    // convert the values to unsigned char (BYTE) 
    for(int i=0; i<R*C; i++){ 
     if (data[i] == 1){ 
      data[i] = 255; 
     } 
     bmp_data[i] = (unsigned char)data[i]; 
    } 

    delete [] data; 

    return bmp_data; 
} 

這樣的問題/疑問回顧一下:

  1. 白色石灰綠色。
  2. 的HBITMAP是無法一個圖片裏面顯示,該盒setimage叫(是其設置爲SS_BITMAP)
  3. 我相信我可能會丟失從創建位圖的一些信息,我想我需要後變爲純黑色儘管我不確定,但實現設備上下文。我可以在Windows中打開文件,但如果我嘗試在線上傳它不像格式。
  4. 我不知道如何管理對象的內存,所以我得到泄漏,如何在應用程序關閉之前使用DeleteObject清理? (對話框的析構函數可能?)泄漏是262144字節,大約是圖像的大小。

感謝您閱讀這個愚蠢的長期職位。

編輯我設法解決綠色問題(編號1),我不知道如何,我認爲這是與標頭上的內存大小不正確。它仍然無法上傳到互聯網或在程序中顯示,所以一定是錯誤的。

+0

不能看到你釋放由該行分配的緩衝區:'BITMAPINFO * PBMI =(BITMAPINFO *)ALLOCA ....'。另外,你在哪裏刪除這個緩衝區:'bmp_data = new BYTE [R * C];' – cha

+0

它們用於CreateDIBSection,如果我在返回之前刪除它們,我會得到錯誤。我是否認爲一旦HBITMAP對象被刪除(在某些時候),它們都不再存在了?雖然我刪除了'bmfh',因爲在寫入文件後它不需要嗎? – pgwri

回答

0

所以我發現我的代碼在其他應用程序/互聯網上導致錯誤的問題。

其中我爲圖像的高度分配負值以翻轉數據,但這完全是不正確的解決方案。相反:

// convert the integer values to unsigned char (BYTE) BACKWARDS 
for(int i=0; i<R; i++){ 
    for(int j=0; j<C; j++){ 
     if (data[i*R + j] == 1 && binary){ 
      data[i*R + j] = 255; 
     } 
     bmp_data[(R-i)*C + (j-C)] = (unsigned char)data[i*C + j]; 
    } 
} 

這樣做是複製原始值到bmp_data都向後翻轉。這可確保數據正確存儲並在應用程序中打開。我目前的DIBSection和內存管理解決方案是刪除所有數據,然後從文件中重新加載圖像。通過HBITMAP太麻煩了。我歡迎那方面的意見,但現在我所有的問題都得到了解決。

相關問題