我正在构建一个功能,用另一种目标颜色替换BMP图像中的颜色。 只要我不尝试替换需要填充的图像中的颜色,它就可以工作。 但是,我几乎可以肯定我的帐户填充方式是正确的。所以对我来说这是一个完全的谜。
330 x 250(248 054 bytes)Hi-color 24bit bitmap
这是功能:
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;
}
我可能做错了什么?
答案 0 :(得分:3)
处理位图时,您需要知道三个参数:高度,宽度和步幅。宽度和高度都很明显。 stride
是每行的字节数,包括填充。
这是计算stride
的一种方法。请注意,stride
必须是4的倍数。
int stride = ((width * 3) + 3) >> 2;
stride *= 4;
第一行计算可容纳一行的最小4字节值。第二行将stride
转换为字节数。
本文末尾的代码演示了如何使用步幅。该代码假定输入文件包含24bpp RGB图像。文件头已经被读取,只留下像素数据,这些数据被读入buffer
。代码写入输出文件,假设输出图像与输入图像的大小相同,并且已经写入任何标题。
重要的是
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 );
}