繁体   English   中英

C ++ BMP按位运算符

[英]c++ bmp bitwise operator

 for(unsigned int  h=0; h<ImageBits.iHeight; h++)
  {
        for(unsigned int  w=0; w<ImageBits.iWidth; w++)
        {
              // So in this loop - if our data isn't aligned to 4 bytes, then its been padded
              // in the file so it aligns...so we check for this and skip over the padded 0's
              // Note here, that the data is read in as b,g,r and not rgb as you'd think!
              unsigned char r,g,b;
              fread(&b, 1, 1, fp);
              fread(&g, 1, 1, fp);
              fread(&r, 1, 1, fp);

              ImageBits.pARGB[ w + h*ImageBits.iWidth ] = (r<<16 | g<<8 | b);

        }// End of for loop w

        //If there are any padded bytes - we skip over them here
        if( iNumPaddedBytes != 0 )
        {
              unsigned char skip[4];
              fread(skip, 1, 4 - iNumPaddedBytes, fp);
        }// End of if reading padded bytes

  }// End of for loop h

我不理解此声明以及它如何存储像素的rgb值

ImageBits.pARGB[ w + h*ImageBits.iWidth ] = (r<<16 | g<<8 | b);

我读了<< <<按位移位运算符,但我仍然不明白它是如何工作的。有人可以在这里帮我吗。

您需要将“红色”,“绿色”和“蓝色”的单独值转换为单个变量,因此将它们分别推入16位和8位至“左侧”,以便它们将8位对齐为红色(开始-16),然后得到8位用于绿色(开始-8)和其余颜色。

考虑以下:

 Red   -> 00001111
 Green -> 11110000
 Blue  -> 10101010

Then RGB -> that has 24 bits capacity would look like this initially ->
-> 00000000 00000000 00000000
(there would actually be some random rubbish but it's easier to
demonstrate like this)

Shift the Red byte 16 places to the left, so we get 00001111 00000000 00000000.
Shift the Green byte 8 places to the left, so we have 00001111 11110000 00000000.
Don't shift the Blue byte, so we have 00001111 11110000 10101010.

使用union可以达到类似的结果。 这就是为什么我们要这样做的问题。 访问变量的唯一方法是拥有其地址 (通常绑定到变量名或别名)。

这意味着我们仅具有第一个字节地址,并保证如果它是3字节宽的变量,则紧接我们寻址的字节的以下两个字节属于我们。 因此,我们可以从字面上“向左推位”( 将它们移位 ),以便它们“流入”变量的其余字节。 我们也可以在那里使用指针算术或我已经提到过的指针使用联合。

移位将组成值的位移动指定的数字。

在这种情况下,它是用颜色值完成的,因此您可以在单个4字节结构(例如int)中存储多个1字节的分量(例如RGBA,其范围为0-255)。

取这个字节:

00000011

等于十进制的3。 如果我们要为RGB和A通道存储值3,则需要将此值存储在int(int为32位)中

R        G        B        A
00000011 00000011 00000011 00000011 

如您所见,这些位以4组(每组8个)设置,并且都等于值3,但是当以这种方式存储R值时,如何知道R值是什么呢?

如果摆脱了G / B / A值,您将获得

00000011 00000000 00000000 00000000

哪个仍然不等于3-(实际上,这是一个很大的数字-我认为是12884901888)

为了使该值进入int的最后一个字节,您需要将这些位右移24位。 例如

12884901888 >> 24

然后这些位将如下所示:

00000000 00000000 00000000 00000011

而且您的价值将为“ 3”

基本上,这只是在存储结构中移动位的一种方法,以便您可以更好地操纵值。 将RGBA值放入单个值通常称为填充位

让我们对其进行可视化并将其分为几个步骤,您将看到它很简单。

假设我们有ARGB 32位变量,可以将其视为

int rgb = {a: 00, r: 00, g: 00, b: 00} (当然,这不是有效的代码,让我们暂时将A排除在外)。

当然,每种颜色的值都是8位。

现在我们要放置一个新值,每种颜色有三个8位变量:

unsigned char r = 0xff, g=0xff, b=0xff

我们实际上要做的是获取一个32位变量,然后执行以下操作:

rgb |= r << 16 (将红色的16位左移。它右边的所有内容将保持为0)

所以现在我们有了

rgb = [a: 00, r: ff, g: 00, b: 00]

现在我们做:

rgb = rgb | (g << 8) rgb = rgb | (g << 8) (表示取现值并与绿色进行“或”运算,移至其位置)

所以我们有[a: 00, r: ff, g: ff, b: 00]

最后...

rgb = rgb | b rgb = rgb | b (表示取值并将其与蓝色的8位进行“或”运算,其余保持不变)

给我们留下[a: 00, r: ff, g: f, b: ff]

代表32位(实际上是24,因为Alpha与该示例无关)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM