2017-06-20 76 views
-1

我的程序需要能够读取.bmp图像,在其中写入一些数据,然后创建另一个.bmp图像。首先,我开始编写一些东西来读取图像,并在另一个文件中重写相同的图像,但是我遇到了一些问题。 这里是我的代码:在读取/写入.bmp文件时遇到困难C

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"); 
} 

它似乎总是在 “无法写入图像数据” 错误脱落。有人能帮助我吗?我对编程相当陌生,无法自行修复。

+1

使用调试器并找出原因。 –

+0

您应该使用在Windows中定义的位图标头。 H。 https://msdn.microsoft.com/en-us/library/windows/desktop/dd183375(v=vs.85).aspx –

+0

@MichaëlRoy使用的头文件('unistd.h')表明代码是*尼克斯。 –

回答

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,,你能指望什么发生?使用随机值填充剩余的字节?与零?无论如何,你应该明确地写出这些字节。

0

所以,我确实找到了解决我的问题的方法。麻烦的是,当一个BMP未压缩文件,在BMP_Info_Header结构发现imageSize变量的值等于0,所以当我打电话给freadfwrite功能,他们不会读或写任何东西,因为header->imageSize值0.我找到的解决方案是用header->imageSize调用3 * header->width * header->height,这样我就可以得到真实的图像分辨率,并将其乘以3,以便我可以得到确切的像素值。顺便说一句,感谢帮助家伙!欣赏它!