【发布时间】:2021-04-26 15:00:29
【问题描述】:
我现在正在学习C,我开始写一个BMP图像读取器和写入器,对基本图像进行一些操作。
我正在读取 BMP 图像并将其保存到结构中,然后只需编写一个副本以确保流程正常工作,但是,当我编写图像时,我得到以下结果
左侧是原件,右侧是副本,我不知道是我没有节省足够的内存还是我没有以正确的方式写入数据。
我有头文件和实现,我写了两个函数readImage和writeImage,都接收头文件中描述的文件名和Image结构。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdbool.h>
typedef uint16_t ImageType;
typedef struct
{
uint32_t size;
uint16_t additionalFeature;
uint16_t copy;
uint32_t offset;
} ImageHeader;
typedef struct
{
uint32_t headerSize;
int width;
int height;
uint16_t colorSpaces;
uint16_t bitsPerPixel;
uint32_t compression;
uint32_t size;
int verticalResolution;
int horizontalResolution;
uint32_t totalColors;
uint32_t importantColors;
} ImageMetadata;
typedef struct {
int red;
int green;
int blue;
int reserved;
} ImageColors;
typedef unsigned char *ImagePixels;
typedef struct {
ImageType type;
ImageHeader header;
ImageMetadata metadata;
ImagePixels pixels;
} Image;
ImageType BMP_IMAGE_TYPE = 0x4D42;
void readImage(char *filename, Image *image);
void writeImage(char *filename, Image *image);
void fragmentImage(Image *image);
#include "bmp.h"
void readImage(char *filename, Image *image)
{
FILE *imageFile = fopen(filename, "r");
if (!imageFile)
{
perror("ReadImageFileException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fread(&(image->type), sizeof(ImageType), 1, imageFile);
if (image->type != BMP_IMAGE_TYPE)
{
fprintf(stderr, "%hu", image->type);
perror("ReadImageTypeException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fread(&(image->header), sizeof(ImageHeader), 1, imageFile);
fread(&(image->metadata), sizeof(ImageMetadata), 1, imageFile);
image->pixels = (unsigned char *)malloc(image->metadata.width * image->metadata.height);
if (!image->pixels)
{
perror("ReadImagePixelsException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fseek(imageFile, image->header.offset, SEEK_SET);
fread(image->pixels, sizeof(char) * image->metadata.width * image->metadata.height, 1, imageFile);
fclose(imageFile);
}
void writeImage(char *filename, Image *image)
{
FILE *imageFile = fopen(filename, "w+");
if (!imageFile)
{
perror("WriteImageFileException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
int typeWritten = fwrite(&(image->type), sizeof(image->type), 1, imageFile);
if (typeWritten == 0)
{
perror("WriteImageTypeException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
int headerWritten = fwrite(&(image->header), sizeof(image->header), 1, imageFile);
if (headerWritten == 0)
{
perror("WriteImageHeaderException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
int metadataWritten = fwrite(&(image->metadata), sizeof(image->metadata), 1, imageFile);
if (metadataWritten == 0)
{
perror("WriteImageMetadataException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fseek(imageFile, image->header.offset, SEEK_SET);
int pixelsWritten = fwrite(image->pixels, sizeof(char) * image->metadata.width * image->metadata.height, 1, imageFile);
if (pixelsWritten == 0)
{
perror("WriteImagePixelsException");
fclose(imageFile);
exit(EXIT_FAILURE);
}
fclose(imageFile);
}
在主文件中,我声明了图像数据结构并将其传递给两个函数
#include "bmp.c"
int main() {
Image image;
readImage("image.bmp", &image);
writeImage("image-copy.bmp", &image);
return 0;
}
¿有人可以帮助确定我做错了什么?我已经尝试分配更多内存或计算保存像素的数据结构的大小以及保存图像大小的标题,但它没有工作。
【问题讨论】:
-
每个像素有 3 个值吗?
-
不,所有的图像数据/像素都保存在一个字符指针中。
-
您似乎只写了图片的 1/3?可能是一些尺寸问题,你需要乘以 3? (AKA 它是彩色图像而不是灰度图像)
-
@Mikhail - 不错。 288 像素高,目前有 96 个。这里可能值得一提的是,图像(虽然这个没有)也可能在每条扫描线的末尾填充。当一个人第一次遇到它时,这有点粗鲁。
-
@enhzflep:“当你第一次遇到它时,这有点粗鲁的惊喜”:我完全支持你!
标签: c image image-processing