我的程序需要能够读取.bmp图像,在其中写入一些数据,然后创建另一个.bmp图像。首先,我开始编写一些东西来读取图像并在另一个文件中重写相同的图像,但我遇到了一些问题。 这是我的代码:
bmp.h:
#ifndef _BMP_H_
#define _BMP_H_
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#pragma pack(push, 1)
typedef struct {
uint16_t type;
uint32_t fileSize;
uint16_t reserved1;
uint16_t reserved2;
uint32_t offset;
} BMP_File_Header;
typedef struct {
BMP_File_Header fileHeader;
uint32_t bSize;
int32_t width;
int32_t height;
uint16_t planes;
uint16_t bitCount;
uint32_t compression;
uint32_t imageSize;
int32_t xPixelsPerMeter;
int32_t yPixelsPerMeter;
uint32_t colorUsed;
uint32_t importantColor;
} BMP_Info_Header;
#pragma pack(pop)
BMP_Info_Header* loadBMP(const char *filename, char *data);
void writeBMP(BMP_Info_Header *infoHeader, char *data);
#endif
bmp.c:
#include "bmp.h"
BMP_Info_Header* loadBMP(const char *file_name, char *data) {
FILE *file;
BMP_Info_Header *infoHeader;
int n;
//Open the file
file = fopen(file_name, "rb");
if (!file) {
fprintf(stderr, "Failed to read file %s.\n", file_name);
exit(1);
}
//Alloc and read the headers
infoHeader = (BMP_Info_Header *) malloc (sizeof(BMP_Info_Header));
n = fread(infoHeader, sizeof(BMP_Info_Header), 1, file);
//Check format
if (infoHeader->fileHeader.type != 0x4D42) {
fclose(file);
fprintf(stderr, "Invalid image");
exit(1);
}
//-------------------------Checking the image--------------------------
if (infoHeader->bSize != 40) {
fclose(file);
fprintf(stderr, "Couldn't load image correctly");
exit(1);
}
if ((infoHeader->planes != 1) || (infoHeader->bitCount != 24)) {
fclose(file);
fprintf(stderr, "Invalid image");
exit(1);
}
if (infoHeader->compression != 0) {
fclose(file);
fprintf(stderr, "This software currently does not support compressed BMP files.\n");
exit(1);
}
//Move the file through the offset until the beginning of the data itself
fseek(file, sizeof(char) * infoHeader->fileHeader.offset, SEEK_SET);
//Allocate the char array to the needed size to hold the data
data = (char *) malloc (sizeof(char) * infoHeader->imageSize);
//Actually read the image data
fread(data, sizeof(char), infoHeader->imageSize, file);
printf("%s", data);
//Verify the data
if (!data) {
fclose(file);
fprintf(stderr, "Couldn't load image data correctly\n");
exit(1);
}
fclose(file);
return infoHeader;
}
void writeBMP(BMP_Info_Header *header, char *data){
FILE *fp;
fp = fopen("output.bmp", "wb");
int n;
if (!fp) {
fclose(fp);
fprintf(stderr, "Unable to create output file\n");
exit(1);
}
//-----------------------WRITE THE IMAGE------------------------
//Header
n = fwrite(header, sizeof(char), sizeof(BMP_Info_Header), fp);
if (n < 1) {
fclose(fp);
fprintf(stderr, "Couldn't write the image header.\n");
exit(1);
}
//Offset
fseek(fp, sizeof(char) * header->fileHeader.offset, SEEK_SET);
//Data
n = fwrite(data, sizeof(char), header->imageSize, fp);
if (n < 1) {
fclose(fp);
fprintf(stderr, "Couldn't write the image data.\n");
exit(1);
}
fclose(fp);
fprintf(stdout, "Image written successfully!\n");
}
似乎总是在“无法写入图像数据”错误时掉线。有人能帮助我吗?我对编程很新,无法自己解决。
答案 0 :(得分:1)
所以,我确实找到了解决问题的方法。麻烦的是,当未压缩BMP文件时,imageSize
结构中找到的BMP_Info_Header
变量中的值等于0,所以当我调用fread
和{{1}时函数,他们不会读或写任何东西,因为fwrite
的值为0.我找到的解决方案是用header->imageSize
调用header->imageSize
来代替,这样我就可以得到真实的图像分辨率,我乘以3,这样我就可以得到精确的像素值。顺便说一句,谢谢你的帮助!欣赏它!
答案 1 :(得分:0)
可能问题在于fseek
,您不会检查返回值。
fwrite(header, sizeof(char), sizeof(BMP_Info_Header), fp);
fseek(fp, sizeof(char) * header->fileHeader.offset, SEEK_SET);
fwrite(data, sizeof(char), header->imageSize, fp);
请注意,如果您在撰写标题后的当前位置小于fileHeader.offset,
,您预计会发生什么?用随机值填充剩余的字节?零?在任何情况下,您都应该显式写入这些字节。