Вы неправильно заполняете свой массив битов.
Вы создаете 1-битное (монохромное) восходящее растровое изображение. Каждый отдельный бит в вашем массиве представляет отдельный пиксель, где бит 0
относится к первому цвету, а бит 1
относится ко второму цвету в вашей таблице цветов. И первая строка в растровом изображении - это строка последняя в массиве, а последняя строка в растровом изображении - это первая строка в массиве.
0x0F
шестнадцатеричный код 00001111
двоичный. Вы устанавливаете каждый 8-битный char
в своем массиве на 0x0f
, поэтому вы создаете чередующийся шаблон из 4 0000
битов, за которыми следуют 4 1111
битов для каждой строки, например:
00001111 00001111 00001111 ... (for 29 more bytes)
00001111 00001111 00001111 ... (for 29 more bytes)
00001111 00001111 00001111 ... (for 29 more bytes)
... (for 253 more rows)
Для растрового изображения 256x256, которое создает 64 чередующихся вертикальных столбца шириной 4 пикселя каждый.
Чтобы получить желаемый эффект - 8 чередующихся горизонтальных полос, каждый из которых имеет высоту 32 пикселя, - необходимо установить для каждого бита в данной строке либо все 0, либо все 1, а затем вам нужно чередовать этот шаблон в группах по 32 полных ряда, например:
00000000 00000000 00000000 ... (for 29 more bytes)
00000000 00000000 00000000 ... (for 29 more bytes)
00000000 00000000 00000000 ... (for 29 more bytes)
... (for 29 more rows)
11111111 11111111 11111111 ... (for 29 more bytes)
11111111 11111111 11111111 ... (for 29 more bytes)
11111111 11111111 11111111 ... (for 29 more bytes)
... (for 29 more rows)
... (repeat the above 4 more times)
Попробуйте вместо этого что-нибудь еще:
// Build monochrome array of bits in image
bool isWhite = false;
for (int i = 0; i < IMAGE_SIZE; ) {
char ch = isWhite ? 0xFF : 0x00;
int row = (IMAGE_SIZE - 1) - i; // use row = i for a top-down bitmap ...
for (int col = 0; col < (IMAGE_SIZE / 8); ++col) {
bits[row][col] = ch;
}
// alternatively to the above loop:
// memset(bits[row], isWhite ? 0xFF : 0x00, IMAGE_SIZE / 8);
if ((++i % 32) == 0) isWhite = !isWhite;
}
Или:
// Build monochrome array of bits in image
bool isWhite = true;
for (int i = 0; i < IMAGE_SIZE; ++i) {
if ((i % 32) == 0) isWhite = !isWhite;
int row = (IMAGE_SIZE - 1) - i; // use row = i for a top-down bitmap ...
char ch = isWhite ? 0xFF : 0x00;
for (int col = 0; col < (IMAGE_SIZE / 8); ++col) {
bits[row][col] = ch;
}
// alternatively to the above loop:
// memset(bits[row], isWhite ? 0xFF : 0x00, IMAGE_SIZE / 8);
}
Или:
// Build monochrome array of bits in image
for (int i = 0; i < IMAGE_SIZE; ++i) {
char ch = ((i % 64) < 32) ? 0x00 : 0xFF;
int row = (IMAGE_SIZE - 1) - i; // use row = i for a top-down bitmap ...
for (int col = 0; col < IMAGE_SIZE / 8; ++col) {
bits[row][col] = ch;
}
// alternatively to the above loop:
// memset(bits[row], ((i % 64) < 32) ? 0x00 : 0xFF, IMAGE_SIZE / 8);
}
При этом я бы предложил несколько дополнительных настроек для остальной части вашего кода:
#include <iostream>
#include <fstream>
#include <windows.h>
//#include <string.h> // if using memset() above...
// The following defines the size of the square image in pixels.
#define IMAGE_SIZE 256
// The following defines the size of each row in bytes.
#define BYTES_PER_ROW (IMAGE_SIZE / sizeof(BYTE))
int main()
{
// Define and open the output file.
std::ofstream bmpOut("foo.bmp", std::ios::binary);
if (!bmpOut)
{
std::cerr << "could not open file, ending.";
return -1;
}
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD colorTable[2] = { {0x00,0x00,0x00,0x00}, {0xFF,0xFF,0xFF,0x00} };
// The following defines the array which holds the image bits. The row length
// (number of columns) is the height divided by 8, since there are 8 bits
// in a byte.
BYTE bits[IMAGE_SIZE][BYTES_PER_ROW];
// Initialize the bitmap file header with static values.
bmfh.bfType = 0x4d42;
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmih) + sizeof(colorTable);
bmfh.bfSize = bmfh.bfOffBits + sizeof(bits);
// Initialize the bitmap information header with static values.
bmih.biSize = sizeof(bmih);
bmih.biWidth = IMAGE_SIZE;
bmih.biHeight = IMAGE_SIZE; // positive for bottom-up, negative for top-down
bmih.biPlanes = 1;
bmih.biBitCount = 1;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 2835; // magic number, see Wikipedia entry
bmih.biYPelsPerMeter = 2835;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
// Build monochrome array of bits in image, see above...
// Write out the bitmap.
bmpOut.write(reinterpret_cast<char*>(&bmfh), sizeof(bmfh));
bmpOut.write(reinterpret_cast<char*>(&bmih), sizeof(bmih));
bmpOut.write(reinterpret_cast<char*>(&colorTable), sizeof(colorTable));
bmpOut.write(reinterpret_cast<char*>(&bits), sizeof(bits));
if (!bmpOut)
{
std::cerr << "could not write file, ending.";
return -1;
}
bmpOut.close();
// showing result
ShellExecuteA(NULL, NULL, "foo.bmp", NULL, NULL, SW_SHOW);
// Done.
return 0;
}