我得到
传递“fread”的参数1使指针从整数变为不带强制转换的整数
当我做
fread((*pArr)[i][j]->b, sizeof(unsigned char), 1, file);
在我的readPixelsBMP
函数中。和
fread(&(*pArr)[i][j]->b, sizeof(unsigned char), 1, file);
使其崩溃但不发出警告。我的程序只是一个程序,它应该读取一个图像并写入同一个图像。下面是我的全部代码:
#include <stdio.h>
#include <stdlib.h>
struct BMP_Header {
char signature[2];
int size;
short reserved1;
short reserved2;
int offset_pixel_array;
};
struct DIB_Header{
int size;
int width;
int height;
short planes;
short bits_per_pixel;
int compression;
int image_size;
int x_per_meter;
int y_per_meter;
int colors_in_table;
int important_colors;
};
struct Pixel{
unsigned char r;
unsigned char b;
unsigned char g;
};
void readBMPHeader(FILE* file, struct BMP_Header* header) {
fread(&header->signature, sizeof(char) *2, 1,file);
fread(&header->size, sizeof(int), 1,file);
fread(&header->reserved1, sizeof(short), 1,file);
fread(&header->reserved2, sizeof(short), 1,file);
fread(&header->offset_pixel_array, sizeof(int), 1,file);
}
void readDIBHeader(FILE* file, struct DIB_Header* header) {
fread(&header->size, sizeof(int), 1,file);
fread(&header->width, sizeof(int), 1,file);
fread(&header->height, sizeof(int), 1,file);
fread(&header->planes, sizeof(short), 1,file);
fread(&header->bits_per_pixel, sizeof(short), 1,file);
fread(&header->compression, sizeof(int), 1,file);
fread(&header->image_size, sizeof(int), 1,file);
fread(&header->x_per_meter, sizeof(int), 1,file);
fread(&header->y_per_meter, sizeof(int), 1,file);
fread(&header->colors_in_table, sizeof(int), 1,file);
fread(&header->important_colors, sizeof(int), 1,file);
}
void readPixelsBMP(FILE* file, int width, int height, struct Pixel (**pArr)[width][height]) {
*pArr = malloc( sizeof(struct Pixel[width][height]) );
if (*pArr == NULL) {
printf("Error! Insufficient memory!");
return;
}
int padding = (4 - ((3*width) % 4)) % 4;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
//fread(*pArr, sizeof(struct Pixel), 1, file);
fread(&(*pArr)[i][j]->b, sizeof(unsigned char), 1, file);
//fread((*pArr)[i][j]->r, sizeof(unsigned char), 1, file);
//fread((*pArr)[i][j]->g, sizeof(unsigned char), 1, file);
}
if (padding) {
fseek(file, padding, SEEK_CUR);
}
}
fclose(file);
}
void writeBMPHeader(FILE* file, struct BMP_Header* header) {
fwrite(&header->signature, sizeof(char) *2, 1,file);
fwrite(&header->size, sizeof(int), 1,file);
fwrite(&header->reserved1, sizeof(short), 1,file);
fwrite(&header->reserved2, sizeof(short), 1,file);
fwrite(&header->offset_pixel_array, sizeof(int), 1,file);
}
void writeDIBHeader(FILE* file, struct DIB_Header* header) {
fwrite(&header->size, sizeof(int), 1,file);
fwrite(&header->width, sizeof(int), 1,file);
fwrite(&header->height, sizeof(int), 1,file);
fwrite(&header->planes, sizeof(short), 1,file);
fwrite(&header->bits_per_pixel, sizeof(short), 1,file);
fwrite(&header->compression, sizeof(int), 1,file);
fwrite(&header->image_size, sizeof(int), 1,file);
fwrite(&header->x_per_meter, sizeof(int), 1,file);
fwrite(&header->y_per_meter, sizeof(int), 1,file);
fwrite(&header->colors_in_table, sizeof(int), 1,file);
fwrite(&header->important_colors, sizeof(int), 1,file);
}
void writePixelsBMP(FILE* file, int width, int height, struct Pixel (**pArr)[width][height]) {
int padding = (4 - ((3*width) % 4)) % 4;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
fwrite(*pArr, sizeof(struct Pixel), 1, file);
}
if (padding)
fwrite("0", sizeof(char),padding, file);
}
char eof = 0x00;
fwrite(&eof, sizeof(char), 1, file);
}
int main() {
char* filename = "test1wonderbread.bmp";
char* output = "test3wonderbread.bmp";
FILE* file_input = fopen(filename, "rb");
FILE* file_output = fopen(output, "wb");
struct BMP_Header* header = (struct BMP_Header*) malloc(sizeof(struct BMP_Header));
readBMPHeader(file_input, header);
struct DIB_Header* dib_header = (struct DIB_Header*) malloc(sizeof(struct DIB_Header));
readDIBHeader(file_input, dib_header);
struct Pixel (*pArr)[dib_header->width][dib_header->height];
readPixelsBMP(file_input, dib_header->width, dib_header->height, &pArr);
writeBMPHeader(file_output, header);
writeDIBHeader(file_output, dib_header);
//writePixelsBMP(file_output, dib_header->width, dib_header->height, &pArr);
printf("no errors");
return 0;
}
2条答案
按热度按时间mlnl4t2r1#
发布的代码非常非常复杂,可能没有任何原因。
5 + 11次调用
fread
来获取位图头?5 + 11次调用fwrite
来写相同的头?为什么会这样呢?所有这些都是54字节?.
不算读取实际像素的调用...
我将在这里展示一种读取和写入位图的方法,包括代码和一些参数。这里的基本区别是位图的封装
**我将再次留下一篇长文章,因为我认为在这里有一个完整的代码来读取,绘制和编写
C
位图是有用的。完全可以无视。
一个位图
struct
和几种方法bmp_grad
在任何位图绘制区域上构建类似的东西。考虑到它们的名字,其他函数做的是预期的事情。一个简单的(完整的)实现在文章的结尾。代码的测试和输出如下。
main()
进行测试下面的代码显示了正在使用的函数。该方案:
red.bmp
:bmp_read
从磁盘读取其中一个位图,然后将其保存为blueCopy.bmp
中的副本bmp_grad
绘制条纹并将新位图保存为stripes.bmp
。bmp_setPixel
用于在stripes.bmp
的中心绘制一条11像素高的黑色线条,然后将位图保存为lineset_Pixel.bmp
,如下所示main.c
代码Bitmap.h
头一个可能的
bitmap.c
完整实现注意:在阅读和写入位图数据时,不要忘记将结构体与字边界对齐。它只是在编译器中使用
#pragma
或类似的设置本例输出
一些位图将被写入磁盘。
为什么这样可能更容易?
例如,
bmp_write()
代码封装位图使事情更容易编写,测试和阅读。
bmp_setPixel
作为(另一个)示例用这种方式编写可以很容易地在位图上构建绘图原语。理解这一点的关键是要看到,
将
(x,y)
位图坐标转换为struct
中的像素地址hlswsv352#
你有这么多层次的间接.
(*pArr)[i][j]
是一个指向一维数组的指针。您可以访问整个结构
在
fread
中:或访问特定成员
使用对象而不是
sizeof
中的类型。例如,如果您将成员更改为另一种类型,则转换器将自动更改它。