2014-04-08 91 views
2

我正在嘗試取入.bmp文件,並最終逐個編輯像素,但是我想出了一個問題,在INFOHEADER結構中返回給我的寬度和高度。返回的寬度是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

在十六進制編輯器中打開bmp文件,查看info頭中存在的值。然後調試您的代碼並檢查您在infoheader中讀取的值。

1

對於寬度和高度,您必須使用16位變量(無符號短整型)而不是int。根據Wikipedia,寬度/高度是16位。