我不確定我的電腦是否試圖欺騙我,或者如果我只是爲了發現錯誤而疲憊不堪。幾個小時和幾乎幾天,我試圖用純C編寫一個位圖文件。我沒有格式或填充,但內容的問題。 這是一個MWE。當寫入.bmp文件時發生字節偏移
int main() {
FILE *file;
int w = 256;
int h = 15;
int pad = (4 - ((3 * w) % 4)) % 4;
int filesize = 54 + (3 * w + pad) * h;
// Create file header
unsigned char bmpfileheader[14] = { 'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0 };
bmpfileheader[2] = (unsigned char)(filesize);
bmpfileheader[3] = (unsigned char)(filesize >> 8);
bmpfileheader[4] = (unsigned char)(filesize >> 16);
bmpfileheader[5] = (unsigned char)(filesize >> 24);
// Create Info Header
unsigned char bmpinfoheader[40] = { 40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0 };
bmpinfoheader[4] = (unsigned char)(w);
bmpinfoheader[5] = (unsigned char)(w >> 8);
bmpinfoheader[6] = (unsigned char)(w >> 16);
bmpinfoheader[7] = (unsigned char)(w >> 24);
bmpinfoheader[8] = (unsigned char)(h);
bmpinfoheader[9] = (unsigned char)(h >> 8);
bmpinfoheader[10] = (unsigned char)(h >> 16);
bmpinfoheader[11] = (unsigned char)(h >> 24);
// Create content
// Allocate memory dynamically
unsigned char *bmpcontent = (unsigned char *)calloc(filesize - 54, sizeof(unsigned char));
int index;
// map data values onto blue-red scale
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
index = 3 * i + (3 * w + pad) * j;
// blue
*(bmpcontent + index) = 255-i;
}
}
// Write to file
file = fopen("test.bmp", "w");
fwrite(bmpfileheader, sizeof(bmpfileheader[0]), 14, file);
fwrite(bmpinfoheader, sizeof(bmpinfoheader[0]), 40, file);
fwrite(bmpcontent, sizeof(bmpcontent[0]), filesize - 54, file);
fclose(file);
// free memory
free(bmpcontent);
return 0;
}
,因爲我填的每個像素的「藍色字節」與255-i
我指望得深藍色光滑黑漸變中的每一行。但我發現了這一點: example1
正如你可以看到有在每個引起顏色的每個新行加每隔二行之後的像素移位的變更線字節偏移。奇怪的是,它只發生在我試圖在文件中寫入13
時。使用十六進制編輯器,我發現,在下一個值進入文件之前寫入第二個13。當我將寬度減小到240(現在位圖的內容在14和255之間變化)時,我得到沒有任何移位的平滑圖像:example2
你可以說這是純粹的巧合,而寫一個13,它可能是這樣的。但我也試圖將數據寫入文件,其中13出現在非確定性位置,並且發生了完全相同的效果。
我在我的智慧結尾,請幫助我!
很好的抓住這裏。 –
根據'fwrite man page',在'mode'描述下,'b'標誌僅用於兼容性,並且在包括Linux在內的所有符合POSIX的系統上被忽略。該運營商尚未指出他們正在開發哪個平臺。 – Matt
它在Linux上的工作原理。由於fopen默認爲二進制。 – Matt