Dealing with padding in a BMP file in C

后端 未结 3 1411
一生所求
一生所求 2020-12-20 00:45

I am trying to edit a BMP file in C. My code works for BMP files with no padding but I am having trouble dealing with padding.

There are a few other questions on BMP

相关标签:
3条回答
  • 2020-12-20 01:02

    The problem is in this part:

    int c = 0;
    for (int a = 0; a < height; a++) {
        for (int b = 0; b < width*3; b++) {
            if (bmpArray[a*(width*3)+b] < 127) {
                bmpArray[a*(width*3)+b] = 0;
            } else {
                bmpArray[a*(width*3)+b] = 255;
            }
        }
        for (int pad = 0; pad < padding; pad++) {
            bmpArray[c++] = 0x00;  /* ONLY HERE is 'c' updated! */
        }
    }
    

    At the end of each line, you fill out the padding starting at c, which starts out at 0 and so overwrites the first few bytes of the first line. Then, each next line gets copied but you continue overwriting from the start (where c initially pointed to).

    The padding should be added on each line. In the loops, you adjust a and b but you forget to adjust for the padding.

    I suggest the more straightforward code (untested!):

    for (int a = 0; a < height; a++) {
        for (int b = 0; b < width*3; b++) {
            if (bmpArray[a*(width*3 + padding)+b] < 127) {
                bmpArray[a*(width*3 + padding)+b] = 0;
            } else {
                bmpArray[a*(width*3 + padding)+b] = 255;
            }
        }
        for (int pad = 0; pad < padding; pad++) {
            bmpArray[a*(width*3 + padding) + 3*width + pad] = 0x00;
        }
    }
    

    is there a way I can identify the padding pixels ..

    Yes – in my loop above with adjustments for padding, it automatically skips the padding itself. You can safely remove the explicit 'set padding to 0' loop at the end.

    0 讨论(0)
  • 2020-12-20 01:07

    Something like:

    ...
    
    int originalLineSize = width * 3;
    int workLineSize = originalLineSize + 4 - originalLineSize % 4;
    
    for (int a = 0; a < bmpArraySize; ++a) {
        if ((a % workLineSize) >= originalLineSize)
            bmpArray[a] = 0x00;
        }
        else if (bmpArray[a] < 127) {
            bmpArray[a] = 0;
        ...
    }
    
    0 讨论(0)
  • 2020-12-20 01:21

    The "padding bytes" are the bytes following the pixels of a scanline. You are not so interested in the padding as in the scanline size and pixel size:

    iScanlineSize  = ((width * bitsperpixel) + 31) / 32 * 4;
    iBytesperPixel = bitsperpixel / 8;
    

    Now you can loop over scanlines and adress pixels and pixel parts (colors) as follows:

    for (int a = 0; a < height; a++) {
        for (int b = 0; b < width; b++) {
            for (int c = 0; c < iBytesperPixel; c++) {
                pixelPart= bmpArray[a*iScanlineSize + b*iBytesperPixel + c];
            }
        ]
    }
    
    0 讨论(0)
提交回复
热议问题