我正在尝试使用以下代码读取 BMP 图像的像素。首先,我使用我的函数“readBMPHeader”读取相关图像数据(宽度、高度和标题)。接下来我想使用函数“mapBMP”逐行读取文件的像素。但是,我得到的 bmp 图像“dali”的像素值(您可以在下面找到)不正确,我不知道我做错了什么。你能告诉我我的错在哪里吗?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//Macros
#define ALIGNMENT 4
#define HEADER_LOCATION 0x0000
#define DATA_START_LOCATION 0x000A
#define WIDTH_LOCATION 0x0012
#define HEIGHT_LOCATION 0x0016
#define BITS_PER_PIXEL_LOCATION 0x001C
typedef unsigned char byte;
int readBMPHeader(unsigned int* image_header, unsigned int* image_height, unsigned int* image_width,
unsigned int* image_start, const char* file_name)
{
// Here we open the given file for reading in binary mode.
FILE* image = fopen(file_name, "rb");
// Here we check whether opening the given file was successful.
if (image == NULL)
{
printf("Invalid File\n");
return -1;
}
// Here we read in the header of the given BM image.
fseek(image, HEADER_LOCATION, SEEK_SET);
fread(image_header, 2, 1, image);
// Here we read in the height of the given BM image.
fseek(image, HEIGHT_LOCATION, SEEK_SET);
fread(image_height, 4, 1, image);
// Here we read in the width of the given BM image.
fseek(image, WIDTH_LOCATION, SEEK_SET);
fread(image_width, 4, 1, image);
fseek(image, DATA_START_LOCATION, SEEK_SET);
fread(image_start, 4, 1, image);
fclose(image);
return 0;
}
void mapBMP(unsigned int height, unsigned int width, char mapped_image[height][width], unsigned int image_start, const char* file_name)
{
FILE* image = fopen(file_name, "rb");
// Here we read in the number of bits per pixel in the given BM image.
unsigned int bits_per_pixel;
fseek(image, BITS_PER_PIXEL_LOCATION, SEEK_SET);
fread(&bits_per_pixel, 2, 1, image);
// Here we compute the number of bytes per pixel in the given BM image.
unsigned int bytes_per_pixel = ((unsigned int) bits_per_pixel) / 8;
// Here we compute the stride, i.e. the number of bytes in a row (rounded up by alignment)
unsigned int stride = (width * bytes_per_pixel) + (ALIGNMENT - 1);
stride /= ALIGNMENT;
stride *= ALIGNMENT;
// Here we read in the pixels of the image, the loops have been shortened for testing purposes.
byte pixel[bytes_per_pixel];
for (unsigned int i = height - 1; i > height - 2; i = i - 1) // The proper condition is:(unsigned int i = height - 1; i > 0; i = i - 1)
{
fseek(image, i * stride, image_start);
for (unsigned int j = 0; j < 30; j = j + 1) // The proper condition is: (unsigned int j = 0; j < width; j = j + 1)
{
fread(pixel, 3, 1, image);
printf("pixel = %x %x %x\n", pixel[0], pixel[1], pixel[2]);
}
}
fclose(image);
}
int main()
{
// Here is the BMP Image test.
unsigned int image_header;
unsigned int image_width;
unsigned int image_height;
unsigned int image_start;
char* file_name = "dali.bmp";
int file_opened = readBMPHeader(&image_header, &image_height, &image_width, &image_start, file_name);
if (file_opened == -1)
printf("File could not be opened.");
else
{
// Some prints to see the collected data.
printf("Size of byte in byte = %llu \n", sizeof(byte));
printf("header (in hex) = %x \n", image_header);
printf("height (in pixels) = %u \n", image_height);
printf("width (in pixels) = %u \n", image_width);
printf("image_start (in bytes) = %u \n", image_start);
char mapped_image[image_height][image_width];
mapBMP(image_height, image_width, mapped_image, image_start, file_name);
//printTable(image_height, image_width, mapped_image);
}
return 0;
}
除了将16位读成32位整数外,图片至少有这个问题
张贴图片显示为压缩文件大小 675K 字节。 @Chris Dodd
读取文件并保存为 24 位/像素生成 1133KB 文件。
OP 的代码无法正确读取发布的文件。
将文件重新保存为未压缩的 24 位/像素(全彩色)并重试。
更好的代码会测试和报告标头的所有十六进制数据,以确保预期的编码。
最好使用固定宽度
uint8_t, uint16_t, uint32_t
类型而不是char, unsigned
来读取文件。
Ref BMP 文件格式