【问题标题】:RGB Int to RGB - PythonRGB Int 到 RGB - Python
【发布时间】:2017-04-18 16:22:52
【问题描述】:

如何将 RGB 整数转换为对应的 RGB 元组 (R,G,B)?看起来很简单,但我在 google 上找不到任何东西。

我知道对于每个 RGB (r,g,b) 你都有整数 n = r256^2 + g256 + b,我如何在 Python 中解决相反的问题,IE 给出了 n,我需要 r,g,b价值观。

【问题讨论】:

  • RGB整数是什么意思?
  • shodor.org/stella2java/rgbint.html,只是我刚刚在问题中编辑的公式。 (255, 255, 255) = 16777215
  • 注意:int 255 是“红色”:“#ff0000”,

标签: python integer rgb


【解决方案1】:

从一个 RGB 整数:

Blue =  RGBint mod 256
Green = RGBint / 256 mod 256
Red =   RGBint / 256 / 256 mod 256

一旦您知道如何获得它,就可以非常简单地实现它。 :)

更新:新增 python 功能。不确定是否有更好的方法,但这适用于 Python 3 和 2.4

def rgb_int2tuple(rgbint):
    return (rgbint // 256 // 256 % 256, rgbint // 256 % 256, rgbint % 256)

Nils Pipenbrinck 发布的还有一个使用位移和掩码的出色解决方案,其速度无疑要快得多。

【讨论】:

  • 不要忘记使用整数除法而不是浮点除法。
  • 尽管它使用整数除法和模数,但我认为我的答案不值得降级。
  • 不,它不值得被否决。人们没有阅读过投反对票的工具提示,并认为投反对票的意思是“我不喜欢这个”。
【解决方案2】:

这可能有更短的方法:

dec=10490586
hex="%06x" % dec
r=hex[:2]
g=hex[2:4]
b=hex[4:6]
rgb=(r,g,b)

编辑:这是错误的 - 以十六进制给出答案,OP 想要 int。 EDIT2:改进以减少痛苦和失败 - 需要 '%06x' 以确保十六进制始终显示为六位数 [感谢彼得汉森的评论]。

【讨论】:

  • 如果十六进制字符串没有预期的六位数,这也会失败。使用“%06x”来避免这种情况。
【解决方案3】:

我绝对不是 Python 专家,但据我所知,它具有与 C 相同的运算符。

如果是这样,这应该可以工作,而且应该比使用模数和除法快很多。

Blue =  RGBint & 255
Green = (RGBint >> 8) & 255
Red =   (RGBint >> 16) & 255

在每种情况下屏蔽最低字节的作用(二进制和 255.. 等于 8 个 1 位)。对于绿色和红色分量,它的作用相同,但首先将颜色通道转移到最低字节。

【讨论】:

  • +1 但是,与使用 % 和 // 的解决方案相比,速度优势应该是最小的。当然比使用函数调用(divmod、struct.[un]pack 等)的解决方案要快得多。
【解决方案4】:

我假设您有一个包含 RGB 值的 32 位整数(例如 ARGB)。然后你可以使用struct模块解压二进制数据:

# Create an example value (this represents your 32-bit input integer in this example).
# The following line results in exampleRgbValue = binary 0x00FF77F0 (big endian)
exampleRgbValue = struct.pack(">I", 0x00FF77F0)

# Unpack the value (result is: a = 0, r = 255, g = 119, b = 240)
a, r, g, b = struct.unpack("BBBB", exampleRgbValue)

【讨论】:

  • 与其他解决方案相比会非常慢(2 个函数调用)
【解决方案5】:
def unpack2rgb(intcol):
    tmp, blue= divmod(intcol, 256)
    tmp, green= divmod(tmp, 256)
    alpha, red= divmod(tmp, 256)
    return alpha, red, green, blue

如果只接受divmod(value, (divider1, divider2, divider3…)) 的建议,它也会简化各种时间转换。

【讨论】:

    【解决方案6】:
    >>> import struct
    >>> str='aabbcc'
    >>> struct.unpack('BBB',str.decode('hex'))
    (170, 187, 204)
    
    for python3:
    >>> struct.unpack('BBB', bytes.fromhex(str))
    

    >>> rgb = (50,100,150)
    >>> struct.pack('BBB',*rgb).encode('hex')
    '326496'
    
    for python3:
    >>> bytes.hex(struct.pack('BBB',*rgb))
    

    【讨论】:

      【解决方案7】:
      >>> r, g, b = (111, 121, 131)
      >>> packed = int('%02x%02x%02x' % (r, g, b), 16)
      

      这会产生以下整数:

      >>> packed
      7305603
      

      然后你可以用很长的显式方式解压它:

      >>> packed % 256
      255
      >>> (packed / 256) % 256
      131
      >>> (packed / 256 / 256) % 256
      121
      >>> (packed / 256 / 256 / 256) % 256
      111
      

      ..或者以更紧凑的方式:

      >>> b, g, r = [(packed >> (8*i)) & 255 for i in range(3)]
      >>> r, g, b
      

      示例适用于任意位数,例如 RGBA 颜色:

      >>> packed = int('%02x%02x%02x%02x' % (111, 121, 131, 141), 16)
      >>> [(packed >> (8*i)) & 255 for i in range(4)]
      [141, 131, 121, 111]
      

      【讨论】:

        【解决方案8】:

        仅供使用 Google 的 Appengine Images Python API 的任何人注意。我发现我不得不提供一个具有 32 位 RGB 颜色值的方法。

        具体来说,如果您使用 API 转换 PNG(或任何具有透明像素的图像),则需要为 execute_transforms 方法提供一个名为 transparent_substitution_rgb 的参数,该参数必须是 32 位 RGB 颜色值.

        借用dbr的回答,我想出了一个类似这样的方法:

        def RGBTo32bitInt(r, g, b):
          return int('%02x%02x%02x' % (r, g, b), 16)
        
        transformed_image = image.execute_transforms(output_encoding=images.JPEG, transparent_substitution_rgb=RGBTo32bitInt(255, 127, 0))
        

        【讨论】:

          【解决方案9】:

          如果您使用 NumPy 并且您有一个 RGBint 数组,您也可以只更改其 dtype 以提取红色、绿色、蓝色和 alpha 分量:

          >>> type(rgbints)
          numpy.ndarray
          >>> rgbints.shape
          (1024L, 768L)
          >>> rgbints.dtype
          dtype('int32')
          >>> rgbints.dtype = dtype('4uint8')
          >>> rgbints.shape
          (1024L, 768L, 4L)
          >>> rgbints.dtype
          dtype('uint8')
          

          【讨论】:

            【解决方案10】:

            添加到上面提到的内容。一种简洁的单行替代方案。

            # 2003199 or #E190FF is Dodger Blue.
            tuple((2003199 >> Val) & 255 for Val in (16, 8, 0))
            # (30, 144, 255)
            

            为了避免将来出现任何混乱。

            from collections import namedtuple
            RGB = namedtuple('RGB', ('Red', 'Green', 'Blue'))
            rgb_integer = 16766720  # Or #ffd700 is Gold.
            # The unpacking asterisk prevents a TypeError caused by missing arguments.
            RGB(*((rgb_integer >> Val) & 255 for Val in (16, 8, 0)))
            # RGB(Red=255, Green=215, Blue=0)
            

            【讨论】:

              【解决方案11】:
              def int2color(red,green,blue):
                  def chex(c):
                      if c < 16:
                          return "0"+hex(c)[2:]
                      else:
                          return hex(c)[2:]
              
                  return "#{}{}{}".format(chex(red),chex(green),chex(blue))
              
              >>> int2color(49, 105, 0)
              #316900
              

              【讨论】:

              • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
              猜你喜欢
              • 2015-06-16
              • 1970-01-01
              • 1970-01-01
              • 2019-11-27
              • 2015-12-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多