用黑色填充所有位图 1bpp
Filling all bitmap 1bpp with black
我尝试用黑色填充我所有的位图 1bpp,但仍然遗漏了一些像素。
我用 C:
写了那个代码
void fillBlack(void* img, int width, int height)
{
int i=0,j=0;
for(i=0;i<width;i++)
{
for(j=0;j<(height);j+=8)
{
*(char*)(img)=(*((char*)(img))^0xff);
img++;
}
}
}
其中 img 是指向偏移量的指针,所有参数都很好,尤其是宽度和高度。
我做错了什么?
假设 0 表示黑色,您的 XOR 将翻转任何区域的值。假设您有一个二进制值为 00001000
:
的 1 字节区域
black black black black white black black black
white white white white white white white white
-----------------------------------------------
white white white white black white white white
将您的区域归零的等效且更有效的方法是:
char *bmp = img;
memset(bmp, 0, width * (height / 8));
如果 1 表示黑色,0 表示白色(出于某些奇怪的原因):
char *bmp = img;
memset(bmp, 0xff, width * (height / 8));
无论哪种情况,您都不想对这些值进行异或运算。 XOR 翻转不匹配的值。你只是想做一个任务。因此,如果您出于某种原因没有 memset:
void
fillBlack(void *img, int width, int height)
{
char *bmp = img;
int i=0,j=0;
for (i = 0; i < width; i++) {
for(j = 0; j < height; j += 8) {
*bmp++ = 0;
}
}
}
(同样,如果黑色出于某种奇怪的原因在您的格式中不是 0,请将 *bmp++ = 0;
更改为 *bmp++ = 1;
。)
memset(3)
可能在您的系统上进行了优化以一次处理多个字节,假设您 运行 在现代 OS 上并且有一个 CPU 支持这种东西。
Each row of pixels must be a multiple of 4 bytes
suggest:
void fillBlack(void* img, int width, int height)
{
char *pImage = img;
int i=0; // loop counter, image height in pixels
int j=0; // loop counter, image width in pixels
int pad=0; // loop counter, pad bytes at end of each row of pixels
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
*pImage = 0x00;
pImage++; // step to next byte in row
} // end for - width
// there can be some filler bytes on the end of rows
// as rows must be a multiple of 4 bytes
for(pad=0; 0 != (width+pad)%4; pad++)
{
*pImage = 0x00; // set pad byte
pImage++; // step by pad byte
} // end for - pad bytes
} // end for - height
} // end function: fillBlack
位图图像由带像素的扫描线组成。扫描线四舍五入到最接近的单词。假设每个字 32 位:
fillBlack(void *img, int width, int height)
{
char *bmp = img;
int i,j, scanlinebytes;
scanlinebytes= ((width*1)+31) / 32 * 4; // 1 = bits per pixel
for (i = 0; i < height; i++) {
for(j = 0; j < scanlinebytes; j++) {
*bmp++ = 0;
}
}
}
我尝试用黑色填充我所有的位图 1bpp,但仍然遗漏了一些像素。
我用 C:
写了那个代码void fillBlack(void* img, int width, int height)
{
int i=0,j=0;
for(i=0;i<width;i++)
{
for(j=0;j<(height);j+=8)
{
*(char*)(img)=(*((char*)(img))^0xff);
img++;
}
}
}
其中 img 是指向偏移量的指针,所有参数都很好,尤其是宽度和高度。
我做错了什么?
假设 0 表示黑色,您的 XOR 将翻转任何区域的值。假设您有一个二进制值为 00001000
:
black black black black white black black black
white white white white white white white white
-----------------------------------------------
white white white white black white white white
将您的区域归零的等效且更有效的方法是:
char *bmp = img;
memset(bmp, 0, width * (height / 8));
如果 1 表示黑色,0 表示白色(出于某些奇怪的原因):
char *bmp = img;
memset(bmp, 0xff, width * (height / 8));
无论哪种情况,您都不想对这些值进行异或运算。 XOR 翻转不匹配的值。你只是想做一个任务。因此,如果您出于某种原因没有 memset:
void
fillBlack(void *img, int width, int height)
{
char *bmp = img;
int i=0,j=0;
for (i = 0; i < width; i++) {
for(j = 0; j < height; j += 8) {
*bmp++ = 0;
}
}
}
(同样,如果黑色出于某种奇怪的原因在您的格式中不是 0,请将 *bmp++ = 0;
更改为 *bmp++ = 1;
。)
memset(3)
可能在您的系统上进行了优化以一次处理多个字节,假设您 运行 在现代 OS 上并且有一个 CPU 支持这种东西。
Each row of pixels must be a multiple of 4 bytes
suggest:
void fillBlack(void* img, int width, int height)
{
char *pImage = img;
int i=0; // loop counter, image height in pixels
int j=0; // loop counter, image width in pixels
int pad=0; // loop counter, pad bytes at end of each row of pixels
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
*pImage = 0x00;
pImage++; // step to next byte in row
} // end for - width
// there can be some filler bytes on the end of rows
// as rows must be a multiple of 4 bytes
for(pad=0; 0 != (width+pad)%4; pad++)
{
*pImage = 0x00; // set pad byte
pImage++; // step by pad byte
} // end for - pad bytes
} // end for - height
} // end function: fillBlack
位图图像由带像素的扫描线组成。扫描线四舍五入到最接近的单词。假设每个字 32 位:
fillBlack(void *img, int width, int height)
{
char *bmp = img;
int i,j, scanlinebytes;
scanlinebytes= ((width*1)+31) / 32 * 4; // 1 = bits per pixel
for (i = 0; i < height; i++) {
for(j = 0; j < scanlinebytes; j++) {
*bmp++ = 0;
}
}
}