2014-04-08 2 views
2

.bmp 파일을 가져 와서 하나씩 픽셀을 편집하려고하는데 폭과 높이 문제가 INFHEADER 구조체에 반환되었습니다. 반환 된 너비는 13107200이고 높이는 65536입니다. 그러나 프로그램을 실행할 때마다 총 60003 개의 총 픽셀이 계산됩니다. 나는 이것이 왜 있는지 전혀 모른다. 어떤 도움이라도 대단히 감사하겠습니다..bmp 헤더 파일을 제대로 읽는 데 문제가 있습니다.

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]){ 
    //define structures 
     typedef struct 
     { unsigned short int Type; /* Magic identifier */ 
      unsigned int Size; /* File size in bytes */ 
      unsigned short int Reserved1, Reserved2; 
      unsigned int Offset; /* Offset to data (in B)*/ 
     }HEADER; /* -- 14 Bytes -- */ 

     typedef struct 
     { unsigned int Size; /* Header size in bytes */ 
      int Width, Height; /* Width/Height of image */ 
      unsigned short int Planes; /* Number of colour planes */ 
      unsigned short int Bits; /* Bits per pixel */ 
      unsigned int Compression; /* Compression type */ 
      unsigned int ImageSize; /* Image size in bytes */ 
      int xResolution, yResolution;/* Pixels per meter */ 
      unsigned int Colors; /* Number of colors */ 
      unsigned int ImportantColors;/* Important colors */ 
     }INFOHEADER; /* -- 40 Bytes -- */ 

     typedef struct 
     { unsigned char Red, Green, Blue; 
     }PIXEL; 

    //make instance of all three structures 
    HEADER data; 
    INFOHEADER data2; 
    PIXEL pixel; 

    //declare file read pointer 
    FILE *file; 

    //declare fileout read pointer 
    //FILE *fileout; //declare file printed file pointer 

    // open file 1 of argument counter and return 0 apon error 
    if(!(file = fopen("CU.bmp","rb")))return 0; 
    //read HEADER data into data 
    fread(&data,sizeof(HEADER),1,file); 
    //read IB+NFOHEADER data into data2 
    fread(&data2,sizeof(INFOHEADER),1,file); 
    //Print PIXEL data  

    //Allocate space for pixelarray 
    PIXEL **pixelarray; 
    int r=0,c=0,rows=data2.Height,collumns=data2.Width; 
    pixelarray= malloc(rows*sizeof(PIXEL *)); 
    for(r=0; r<rows; r++){ 
     pixelarray[r]=malloc(collumns*sizeof(PIXEL)); 
    } 

    //fill pixel array with pixel structs 
    r=0;c=0; 
    int pixelnum=1; 
    while(fread(&pixel,sizeof(PIXEL),1,file)){ 
     if(c == collumns){ 
      c=0; 
      r++; 
     } 
     pixelarray[r][c] = pixel; 
     printf("\nPixel %10d: %02X%02X%02X",pixelnum,pixelarray[r][c].Red,pixelarray[r][c].Blue,pixelarray[r][c].Green); 
     fflush(stdout); 
     c++;pixelnum++; 

    } 

    free(pixelarray); 

    fclose(file); //close the files prior to exiting 
+0

유형 ('int' 및'short')의 크기는 고정되어 있지 않습니다. 32 비트와 16 비트 타입을 원한다면'int32_t'와'int16_t' (또는'uint32_t'와'uint16_t')를 각각 사용하십시오. –

답변

4

문제는 structure alignment입니다. herehere을 참조 할 수 있습니다. 이를 제거하려면 #pragma 지시문을 사용하십시오. 따라서 구조 선언은 다음과 같습니다.

#pragma pack(push) // push current alignment to stack 
#pragma pack(1)  // set alignment to 1 byte boundary 
typedef struct 
{ 
    unsigned short int Type; /* Magic identifier */ 
    unsigned int Size; /* File size in bytes */ 
    unsigned short int Reserved1; 
    unsigned short int Reserved2; 
    unsigned int Offset; /* Offset to data (in B)*/ 
}HEADER; /* -- 14 Bytes -- */ 

typedef struct 
{ 
    unsigned int Size; /* Header size in bytes */ 
    int Width; 
    int Height; /* Width/Height of image */ 
    unsigned short int Planes; /* Number of colour planes */ 
    unsigned short int Bits; /* Bits per pixel */ 
    unsigned int Compression; /* Compression type */ 
    unsigned int ImageSize; /* Image size in bytes */ 
    int xResolution; 
    int yResolution;/* Pixels per meter */ 
    unsigned int Colors; /* Number of colors */ 
    unsigned int ImportantColors;/* Important colors */ 
}INFOHEADER; /* -- 40 Bytes -- */ 

typedef struct 
{ 
    unsigned char Red; 
    unsigned char Green; 
    unsigned char Blue; 
}PIXEL; 
#pragma pack(pop) // restore original alignment from stack 

정확하게 BMP 이미지의 너비와 높이를 읽습니다. 또한 이미지 데이터를 읽는 동안 직접 입력하십시오 :

for(r=0; r<rows; r++) 
{ 
    for(c=0; c<collumns; c++)  // read pixel data from image 
    { 
     fread(&pixelarray[r][c] , 1, sizeof(PIXEL), file); 
     pixelnum++; 
    } 
} 
+0

지금까지 완벽하게 작동했습니다. 참조 용으로도 감사합니다. – user2985363

+0

도와 주시겠습니까? :) – GoldRoger

0

16 진수 편집기에서 bmp 파일을 열고 정보 헤더에 어떤 값이 있는지 확인하십시오. 그런 다음 코드를 디버그하고 infoheader에서 읽은 값을 확인하십시오.

1

너비와 높이에 int 대신 16 비트 변수 (부호없는 short)를 사용해야합니다. Wikipedia에 따르면 너비/높이는 16 비트입니다.

관련 문제