2014-04-08 41 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位。