2017-03-28 14 views
1

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

は、生成ビットマップイメージへのリンクです: Scaled up for clarity

おかげ

答えて

0

BITMAPINFOHEADER documentationに基づいて、あなたがあるためにあなたのビットマップを設定しているように見えますbmih.biBitCount = 1を設定してモノクロとして読み取ります。この方法では、すべてのピクセルはバイトではなく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')? 2次元配列の '(IMAGE_SIZE/8)*(IMAGE_SIZE/8)'サイズの単純な1次元配列を使った方が簡単でしょう。 – slawekwin

関連する問題