2

I have some numbers that I want to interpret as RGB color tuples. The number represents the color like it were in base 256; i.e., the "65536s" digit represents the red component, the "256s" digit represents the green component, and the ones digit represents the blue component.

I wrote some complex code to do this, with a lot of special cases. Do I need my own code for this task? What is the simplest and most direct way to get this result?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Dan2783
  • 53
  • 5
  • 1
    None of this is necessary, not even the tuples. Base 256 is how integers are stored in memory - a byte can have 256 values, so what you ask is the bytes of that number. All libraries can handle an integer as an ARGB or RGB value - that how RGB values are stored in memory. You could just extract the number's bytes if you want, but it's faster to just pass the 4-byte value to your library – Panagiotis Kanavos Nov 26 '20 at 08:10
  • Is this homework? You can use `to_bytes` to get the bytes but the tutor may actually want you to do the math. In real programming though one would **never** perform such calculations, as they are 1000s of times slower than the almost instantaneous extraction of bytes. And once again, all graphics libraries work with `int`s to *avoid* even that kind of extraction. In graphics, speed matters – Panagiotis Kanavos Nov 26 '20 at 08:16
  • Does this answer your question? [Converting int to bytes in Python 3](https://stackoverflow.com/questions/21017698/converting-int-to-bytes-in-python-3) – Panagiotis Kanavos Nov 26 '20 at 08:16
  • You'd expect it to, but the method there only works for single-byte results. – Karl Knechtel Nov 26 '20 at 08:18
  • I came back to the question and rewrote it entirely, to make more sense (and to correspond to the fact that my answer was accepted, which informs/confirms my original understanding of what OP actually wanted). – Karl Knechtel Jul 01 '22 at 13:20

2 Answers2

4

The integer type has this built-in:

>>> help(int.to_bytes)
Help on method_descriptor:

    to_bytes(self, /, length, byteorder, *, signed=False)
        Return an array of bytes representing an integer.
    
        length
          Length of bytes object to use.  An OverflowError is raised if the
          integer is not representable with the given number of bytes.
        byteorder
          The byte order used to represent the integer.  If byteorder is 'big',
          the most significant byte is at the beginning of the byte array.  If
          byteorder is 'little', the most significant byte is at the end of the
          byte array.  To request the native byte order of the host system, use
          `sys.byteorder' as the byte order value.
        signed
          Determines whether two's complement is used to represent the integer.
          If signed is False and a negative integer is given, an OverflowError
          is raised.

Your code produces an unsigned, big-endian result, of length 3, as a tuple of integer values. A bytes object is a sequence that gives you bytes when you iterate over it, so we can feed it directly to tuple to do the necessary conversion. Thus:

def convertBase256(n):
    return tuple(n.to_bytes(3, 'big'))

And we're done.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
1
def convertBase256(n):
 rgb=tuple((n >> Val) & 255 for Val in (16, 8, 0))
 return rgb
AziMez
  • 2,014
  • 1
  • 6
  • 16