1

I had succes reading binary files from BMP file using Vectors to stores the datas before write it on a new file...follow below the code. I realized that this Code could be improved and I found some solutions checking books and Internet. Lots of people wrote the 2nd code below, the problem is that for me it not run well and make any BMP file to single color file. I`m using Xcode5 do compile this program.

for (int i = 0; i <= imageW - 1; i++)
    {
        for (int j = 0; j <= imageH - 1; j++)
        {
            fread(&rgb[i][j], sizeof(RGBTRIPLE), 1, datas);
        }
    }

// open output file
FILE *bmp_blue = fopen("newfile.bmp", "w");
if (bmp_blue == NULL)
{ 
    printf("Could not create\n");
    return 3;
}

// Write output file BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, bmp_blue);

// Write output file BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, bmp_blue);

// go Black
for (int i = 0; i <= imageW - 1; i++)
{
    for (int j = 0; j <= imageH - 1; j++)
    {
        if (rgb[i][j].rgbtRed == 255)
        {
            rgb[i][j].rgbtGreen = 0;
            rgb[i][j].rgbtRed = 0;
            rgb[i][j].rgbtBlue = 0;
        }
    }
}

for (int i = 0; i <= imageW - 1; i++)
{
    for (int j = 0; j <= imageH - 1; j++)
    {
        printf("%d B %d",i,rgb[i][j].rgbtBlue);
        printf(" G %d",rgb[i][j].rgbtGreen);
        printf(" R %d\n",rgb[i][j].rgbtRed);
    } 
}

// Write output file RGBTRIPLE
for (int i = 0; i <= imageW - 1; i++)
{
    for (int j = 0; j <= imageH - 1; j++)
    {
        fwrite(&rgb[i][j], sizeof(RGBTRIPLE), 1, bmp_blue);
    }
}

Code w/o using Vector and iterating the binary file directly with FOR statement.

// Write output file BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, bmp_blue);

// Write output file BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, bmp_blue);

bi.biHeight = abs(bi.biHeight);

// If Red >>> Go Black

// iterate over infile's scanlines
for (int i = 0 ; i < bi.biHeight; i++)
{
    // iterate over pixels in scanline
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE rgb;

        // read RGB triple from infile
        fread(&rgb, sizeof(RGBTRIPLE), 1, bmp_blue);

        // crank down blue in all pixels
        if(rgb.rgbtRed == 255)
        {
            rgb.rgbtBlue = 0;
            rgb.rgbtRed = 0;
            rgb.rgbtGreen = 0;
        }
        // write RGB triple to outfile
        fwrite(&rgb, sizeof(RGBTRIPLE), 1, bmp_blue);
BigBugNoob
  • 53
  • 8
  • There's no accounting for the necessary padding of each line to a multiple of 4 bytes in your code. It's unclear what the actual problem you're having with the code you posted is. You should put together a short self-contained example of exactly what you are trying to do and explain the issues you're having. The problem might be in code we can't see, such as your definitions of `BITMAPFILEHEADER`, `BITMAPINFOHEADER`, and `RGBTRIPLE`. – Retired Ninja Aug 20 '14 at 00:47

1 Answers1

0

To really see what is going on need more code. As @Retired Ninja pointed out a comment. In particular, given 64-bit machines, the size of the various typedefs may need correction.

Some problems

  1. Open the file in binary mode.

    // this line is implied
    FILE *datas = fopen(..., "rb");
    
    // FILE *bmp_blue = fopen("newfile.bmp", "w");
    FILE *bmp_blue = fopen("newfile.bmp", "wb");
    
    // this line is implied
    FILE *bmp_blue = fopen(..., "wb");
    

Minor

  1. Use matching format specifier assuming rgb[i][j].rgbtBlue is unsigned char.

    // printf("%d B %d",i,rgb[i][j].rgbtBlue);
    printf("%d B %hhu", i, rgb[i][j].rgbtBlue);
    
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256