【问题标题】:Filling all bitmap 1bpp with black用黑色填充所有位图 1bpp
【发布时间】:2015-01-06 00:39:04
【问题描述】:

我尝试用黑色填充所有位图 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 是指向偏移量的指针,所有参数都很好,尤其是宽度和高度。

我做错了什么?

【问题讨论】:

  • 你不觉得你有点滥用parantheses吗!
  • 我认为你的意思是 for (j=0; ...,而不是 for (j=k; ...
  • 需要括号... ;)

标签: c bitmap fill


【解决方案1】:

位图图像由带像素的扫描线组成。扫描线四舍五入到最接近的单词。假设每个字 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;
    }
  }
}

【讨论】:

    【解决方案2】:

    假设 0 表示黑色,您的 XOR 将翻转任何区域的值。假设您有一个 1 字节的区域,其二进制值为 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) 可能已在您的系统上进行了优化,可以一次处理多个字节,假设您在现代操作系统上运行并且拥有支持此类事情的 CPU。

    【讨论】:

    • 这行不通(不过是个好主意),因为 .BMP 图像可以在每行像素的末尾有填充字节。
    • memset 工作正常,但 2 个循环(for)的方式仍然留下白色像素。什么是填充字节?
    • 您能否提供最少的代码集来演示问题以及说明问题的输入位图?
    【解决方案3】:
    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
    

    【讨论】:

    • 我很害怕,但它给了我分段错误。但是当我将 j++ 更改为 j+=8 时,它仍然是白色像素。
    猜你喜欢
    • 1970-01-01
    • 2016-06-11
    • 2010-10-29
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    相关资源
    最近更新 更多