首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >写入BMP图像

写入BMP图像
EN

Stack Overflow用户
提问于 2021-01-22 14:14:39
回答 2查看 67关注 0票数 0

我目前正在学习C语言,并开始编写BMP图像读写器,对基本图像进行一些操作。

我正在读取BMP图像并将其保存到一个结构中,然后只需写入一个副本以确保流程正常工作,但是,当我写入该图像时,我会得到以下结果

左边的是原始的,右边的是副本,我不知道我是不是没有节省足够的内存,或者是我没有以正确的方式写入数据。

我有头文件和实现,我在其中编写了两个函数readImagewriteImage,这两个函数都接收头文件中描述的文件名和图像结构。

代码语言:javascript
复制
#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);
代码语言:javascript
复制
#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);
}

在主文件中,我声明了图像数据结构并将其传递给两个函数

代码语言:javascript
复制
#include "bmp.c"

int main() {
    Image image;
    readImage("image.bmp", &image);
    writeImage("image-copy.bmp", &image);
    return 0;
} 

有人能帮我找出我做错了什么吗?我已经尝试分配更多的内存或计算保存像素的数据结构的大小,以及保存图像大小的标题,但它不起作用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-22 14:24:43

代码语言:javascript
复制
fread(image->pixels, sizeof(char) * image->metadata.width * image->metadata.height, 1, imageFile);
代码语言:javascript
复制
fwrite(image->pixels, sizeof(char) * image->metadata.width * image->metadata.height, 1, imageFile);

也许您的原始bmp文件的每个像素大小超过8位?图像似乎只有原始图像的三分之一,所以原始图像可能有24位格式。

试试3 * sizeof(char)怎么样?

票数 0
EN

Stack Overflow用户

发布于 2021-01-22 16:37:39

24 bpp格式的图像需要每个像素三个字节。如有必要,用虚拟字节填充这些行,使其达到下一个大小,即4的倍数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65840161

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档