2017-03-28 209 views
1

我試圖生成代碼,產生1像素設置爲黑色的圖像,問題是當我嘗試將單個像素設置爲黑色時,輸出爲黑色的8個水平像素。我還試圖將上面的像素設置爲黑色,但是它導致水平線位於原始像素上方8個像素處。使用C++位圖時遇到問題

所以我的問題是,我怎麼能改變我的代碼,所以我最終使用位而不是字節在我的圖像?我只想將單個像素設置爲黑色而不是像素的一個字節。

這裏是我的代碼:

#include <iostream> 
#include <fstream> 
#include "windows.h" 
using namespace std; 

#define IMAGE_SIZE 256 
int main(int argc, char* argv[]) 
{ 

    BITMAPFILEHEADER bmfh; 

    BITMAPINFOHEADER bmih; 

    char colorTable[8] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }; 

    char bits[IMAGE_SIZE][IMAGE_SIZE]; 

    ofstream bmpOut("foo.bmp", ios::out + ios::binary); 
    if (!bmpOut) { 
     cout << "could not open file."; 
     return -1; 
    } 
    bmfh.bfType = 0x4d42; 
    bmfh.bfReserved1 = 0; 
    bmfh.bfReserved2 = 0; 
    bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmih) + sizeof(colorTable); 
    bmfh.bfSize = bmfh.bfOffBits + sizeof(bits); 

    bmih.biSize = 40; 
    bmih.biWidth = IMAGE_SIZE; 
    bmih.biHeight = IMAGE_SIZE; 
    bmih.biPlanes = 1; 
    bmih.biBitCount = 1; 
    bmih.biCompression = 0; 
    bmih.biSizeImage = 0; 
    bmih.biXPelsPerMeter = 2835; 
    bmih.biYPelsPerMeter = 2835; 
    bmih.biClrUsed = 0; 
    bmih.biClrImportant = 0; 

    // Here I am initializing a white background for the bitmap image 

    for (int i = 0; i < IMAGE_SIZE; i++) { 
     for (int j = 0; j < IMAGE_SIZE; j++) { 
      bits[i][j] = 255; 
     } 
    } 

    // Here I attempt to set the most bottom left pixel to black and the pixel above it to black as well 

    bits[0][0] = 0; 

    bits[1][0] = 0; 

    char* workPtr; 
    workPtr = (char*)&bmfh; 
    bmpOut.write(workPtr, 14); 
    workPtr = (char*)&bmih; 
    bmpOut.write(workPtr, 40); 
    workPtr = &colorTable[0]; 
    bmpOut.write(workPtr, 8); 
    workPtr = &bits[0][0]; 
    bmpOut.write(workPtr, IMAGE_SIZE*IMAGE_SIZE); 
    bmpOut.close(); 

    system("mspaint foo.bmp"); 

    return 0; 
} 

這裏是位圖圖像的鏈接產生的:基於BITMAPINFOHEADER documentation Scaled up for clarity

感謝

回答

0

看起來你正在設置您的位圖是通過設置bmih.biBitCount = 1以單色讀取。這樣每個像素都由一位(僅黑色或白色)表示,而不是字節。因此,要將左下角像素設置爲黑色,您需要執行bits[0][0] = 127(127 = 0x7F = 01111111b)。要設置它上面的一個,我認爲你需要做bits[1][0] = 127。在這種情況下,我也相信

char bits[IMAGE_SIZE][IMAGE_SIZE/8]; 
... 
for (int i = 0; i < IMAGE_SIZE; i++) { 
    for (int j = 0; j < IMAGE_SIZE/8; j++) { 
     bits[i][j] = 255; 
    } 
} 
... 
workPtr = &bits[0][0]; 
bmpOut.write(workPtr, IMAGE_SIZE*(IMAGE_SIZE/8)); 

就足夠了。

如果您打算使用不同的調色板,您應該設置不同的biBitCount,如我在開始鏈接到的文檔中所述,我想您會希望bmih.biBitCount = 8作爲您的代碼的健康默認設置。

+0

謝謝你的回覆!你澄清說,我設置位時處理二進制,所以我現在明白如何專門設置8個水平像素的任何排列。我確實嘗試了將像素設置爲黑色的方法,但由於某些原因,我無法使其工作。 – michael874

+0

@ michael874,據我所知,設置左下像素工作?你是如何設置更高像素的,你得到了什麼結果?我認爲將這些信息編輯到問題中對我們來說都是最舒服的。 – slawekwin

+0

@ michael874我編輯了我的答案,我對存儲器佈局有些困惑。你嘗試過那樣嗎('bits [1] [0] = 127')?如果你用一個簡單的一維「(IMAGE_SIZE/8)*(IMAGE_SIZE/8)」大小的數組而不是二維數組,那將更容易。 – slawekwin