2017-06-20 8 views
-1

私のプログラムでは、.bmpイメージを読み込み、そこにデータを書き込んだり、別の.bmpイメージを作成する必要があります。始めに、画像を読み込むためにいくつかのものをコーディングし始め、別のファイルに同じ画像を書き直しましたが、いくつか問題がありました。 は、ここに私のコードです:Cでの.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"); 
} 

常に "画像データを書き込むことができませんでした" というエラーで落ちるようです。誰かが私を助けることができますか?私はかなりプログラミングに新しいので、自分でそれを修正することはできませんでした。

+1

デバッガを使用して理由を調べます。 –

+0

Windowsで定義されたビットマップヘッダーを使用する必要があります。 h。 https://msdn.microsoft.com/en-us/library/windows/desktop/dd183375(v=vs.85).aspx –

+0

@MichaëlRoy使用されているヘッダー( 'unistd.h')は、コードが* nix。 @EugeneSh。 –

答えて

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に等しいため、の値が0であったため、freadおよびfwrite関数を呼び出すと、読み書きが行われませんでした。私が見つけた解決策は、header->imageSizeの代わりに3 * header->width * header->heightを呼び出すことで、実際の画像の解像度を得ることができ、3倍して正確なピクセル値を得ることができました。ところで、助けを借りてくれてありがとう!感謝します!

関連する問題