意外输出(BMP)文件

时间:2010-11-01 22:08:14

标签: c

如果我设法创建一个保持8位灰度BMP文件像素值的双数组,我将使用Sobel算子进行边缘检测。执行程序后,它会创建一个奇怪的位图文件:可能缺少什么?感谢帮助!!以下是photos

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

#pragma pack(2)
typedef struct tagBITMAPFILEHEADER {
  unsigned short bfType;
  unsigned int bfSize;
  unsigned short int bfReserved1;
  unsigned short int bfReserved2;
  unsigned int bfOffBits;
} BITMAPFILEHEADER;


#pragma pack()
typedef struct tagBITMAPINFOHEADER {
  unsigned int biSize;
  unsigned int biWidth;
  unsigned int biHeight;
  unsigned short biPlanes;
  unsigned short biBitCount;
  unsigned int biCompression;
  unsigned int biSizeImage;
  unsigned int biXPelsPerMeter;
  unsigned int biYPelsPerMeter;
  unsigned int biClrUsed;
  unsigned int biClrImportant;
} BITMAPINFOHEADER;

typedef struct pixel {
  unsigned char intensity;
} PIXEL;


int main(int argc, char *argv[])
{
   if(argc != 4)
   {
    printf("Usage: %s input.bmp output.bmp output.txt\n", argv[0]);
    exit(-1);
   }

   FILE *filePtr;
   FILE *bin;
   FILE *write;
   BITMAPFILEHEADER bitmapFileHeader;
   BITMAPINFOHEADER bitmapInfoHeader;
   int i, j;

   write = fopen(argv[3], "w");
   filePtr = fopen(argv[1],"rb");
   bin = fopen(argv[2], "wb");
   if (filePtr == NULL)
   {
    printf("File could not opened\n");
    exit(-1);
    }

    fread(&bitmapFileHeader, sizeof(bitmapFileHeader), 1, filePtr);
    fread(&bitmapInfoHeader, sizeof(bitmapInfoHeader), 1, filePtr);

    fwrite(&bitmapFileHeader, 1, sizeof(bitmapFileHeader), bin);
    fwrite(&bitmapInfoHeader, 1, sizeof(bitmapInfoHeader), bin);

    int offset = sizeof(bitmapFileHeader) + sizeof(bitmapInfoHeader);

    if (bitmapFileHeader.bfType !=0x4D42)
    {
    fclose(filePtr);
    printf("Not a bmp file\n");
    exit(-1);
    }

    if(bitmapInfoHeader.biBitCount > 8)
    {
    printf("Only for Gray-scale 8 bits per pixel Image\n");
    printf("%s is %u bits per pixel Image\n", argv[1], bitmapInfoHeader.biBitCount);
    exit(-1);
    }

    fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
    PIXEL **pixelArray = (PIXEL **)malloc(sizeof(PIXEL*)*bitmapInfoHeader.biWidth);

    for(i = 0; i < bitmapInfoHeader.biWidth; i++)
    {
    pixelArray[i] = (PIXEL *)malloc(sizeof(PIXEL)*bitmapInfoHeader.biHeight);
    }   

    if (!pixelArray)
    {
    for(i = 0; i < bitmapInfoHeader.biWidth; i++)
    {
        free(pixelArray[i]);
    }
    free(pixelArray);
    fclose(filePtr);
    printf("Memory could not be allocated\n");
    exit(-1);
    }

    for (i = 0; i < bitmapInfoHeader.biWidth; i++){
    for(j = 0; j < bitmapInfoHeader.biHeight; j++){
        PIXEL pixel;
        fread(&pixel, sizeof(pixel), 1, filePtr);
        fwrite(&pixel, 1, sizeof(pixel), bin);
        pixelArray[i][j].intensity = pixel.intensity;
        fseek(filePtr, sizeof(pixel), SEEK_CUR);
        offset++;
        if(offset == bitmapInfoHeader.biSizeImage)
            break;
    }
    }

    for (i = 0; i < bitmapInfoHeader.biWidth; i++){
    for(j = 0; j < bitmapInfoHeader.biHeight; j++){
        printf("[%d][%d]:%d", i, j, pixelArray[i][j].intensity);
        fprintf(write, "%d ", pixelArray[i][j].intensity);  
    }
        printf("\n");
        fprintf(write, "\n");
    }


    fclose(filePtr); 
    fclose(write);
    fclose(bin);
    for(i = 0; i < bitmapInfoHeader.biWidth; i++)
    {
    free(pixelArray[i]);
    }
    free(pixelArray);

    return 0;

}

1 个答案:

答案 0 :(得分:2)

可能存在的问题是:

  • 你假设sizeof(PIXEL) == 1(它可能不是,因为它是一个结构 - 你应该检查) - 最好将其改为简单的typedef

  • 你没有处理行填充(如果图像宽度不是4的倍数可能会有问题)

  • 可能会有一个调色板,你不允许

您应该检查BMP标头中的字段以查看实际格式是什么,并验证数据的大小是否符合预期。

另请注意,内存分配失败的错误处理已损坏。