c - BMP 颜色替换器 : Algorithm for padding doesn't work

标签 c bitmap padding bmp

我正在构建一个函数,用另一种目标颜色替换 BMP 图像中的颜色。 只要我不尝试替换需要填充的图像中的颜色,它就可以工作。 但是,我几乎可以肯定我的帐户填充方式是正确的。所以对我来说这完全是个谜。


enter image description here


330 x 250(248 054 字节)高色 24 位位图


这是函数:

union
{
    unsigned long ulColor;
    unsigned char byteColor[4];
} oldColor;
union
{
    unsigned long ulColor;
    unsigned char byteColor[4];
} newColor;

typedef unsigned char           BYTE;
typedef unsigned short int      WORD;
typedef unsigned long int       DWORD;
typedef unsigned long long int  DDWORD;

DDWORD
bitfox_color_replace_data
(BYTE *buff, BYTE old_r, BYTE old_g, BYTE old_b, BYTE new_r, BYTE new_g, BYTE new_b)
{
    #define OFFSET_OF_SIZE      0x2
    #define OFFSET_OF_PIXELS    0xA
    #define OFFSET_OF_WIDTH     0x12
    #define OFFSET_OF_HEIGHT    0x16

    DWORD* buffSize     = (DWORD*)&buff[OFFSET_OF_SIZE];
    DWORD* buffPixels   = (DWORD*)&buff[OFFSET_OF_PIXELS];
    DWORD* buffWidth    = (DWORD*)&buff[OFFSET_OF_WIDTH];
    DWORD  buffHeight   = 0;

    BYTE pad            = 0;
    
    DDWORD pixels_replaced = 0;
    DDWORD i;

    oldColor.byteColor[0] = old_b;  newColor.byteColor[0] = new_b;
    oldColor.byteColor[1] = old_g;  newColor.byteColor[1] = new_g;
    oldColor.byteColor[2] = old_r;  newColor.byteColor[2] = new_r;
    
    for(i = (*buffPixels); i < (*buffSize); i += 3)
    {
        if( i == ((*buffPixels) + (((*buffWidth) * 3) + pad) * (buffHeight + 1)) )
        {
            pad = ((*buffWidth) % 4);
            buffHeight++;
            i += pad;
        }
        
        if(!memcmp(buff + i, oldColor.byteColor, 3))
        {
            memcpy(buff + i, newColor.byteColor, 3);

            pixels_replaced++;
        }

    }
    return pixels_replaced;
}

我可能做错了什么?

最佳答案

在处理位图时,需要知道三个参数:高度、宽度和步幅。宽度和高度一目了然。 stride 是每行的字节数,包括填充。

这是计算步幅的一种方法。请注意,stride 必须是 4 的倍数。

int stride = ((width * 3) + 3) >> 2;
stride *= 4;

第一行计算可以容纳一行的 4 字节值的最小数量。第二行将 stride 转换为字节数。

本文末尾的代码演示了如何使用步幅。该代码假定输入文件包含 24bpp RGB 图像。文件头已经被读取,只留下像素数据,它被读入 buffer。代码写入输出文件,假设输出图像与输入图像大小相同,并且所有 header 均已写入。

重要的几行是

size = height * stride;           // total number of bytes in the image, including padding

offset = (y * stride) + (x * 3);  // 'y * stride' is the offset to the beginning of a line
                                  // 'x * 3' computes the byte offset of a particular pixel

for ( x=width*3; x<stride; x++ )  // outputs the padding bytes, if needed,
    fputc( 0, fpout );  

unsigned char *buffer = NULL;

int height = bmpinfo.biHeight;
int width  = bmpinfo.biWidth;

// stride = (width * 3), rounded up to a multiple of 4
int stride = ((width * 3) + 3) >> 2;    
stride *= 4;

// size of the pixel data, including padding
size_t size = height * stride;         

// allocate memory for the pixel data
if ( (buffer = malloc( size )) == NULL )
    error( "Insufficient memory" );

// read the pixel data from the file
if ( fread( buffer, 1, size, fpin ) != size )
    error( "Unable to read image data" );

// process pixels by row and column
for ( y = 0; y < height; y++ )
{
    for ( x = 0; x < width; x++ )
    {
        // get the RGB values from the buffer
        offset = (y * stride) + (x * 3);
        blue  = buffer[offset];
        green = buffer[offset+1];
        red   = buffer[offset+2];

        // mess around with the RGB value here

        // write the new RGB values to the file
        fputc( (int)blue , fpout );
        fputc( (int)green, fpout );
        fputc( (int)red  , fpout );
    }

    // write the padding bytes to the file
    for ( x = width*3; x < stride; x++ )
        fputc( 0, fpout );
}

关于c - BMP 颜色替换器 : Algorithm for padding doesn't work,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28442102/

相关文章:

c - C 和 dlc 编译器出现奇怪的解析错误

c - 在很小的内存中表示非常大的位数组

c - Padding - 加密算法

c - 为什么在这种情况下不会发生填充?

matlab - Matlab 中的零填充

c - C程序中的高级I/O重定向。(简单Shell)

c - 为什么下面的代码中不是 a==0 呢?

c - 如何从编译后的代码中获取c源代码

android - 旋转位图导致 outOfMemoryException

Android:位图中的 RGB 值错误