Convert hex to 15 bit RGB value in python - python

im a beginner with python and want to make a program that converts a hex RGB value to a 15 bit RGB one (5 bits for every color) i heard that it can be done by bitshifts but i don´t get how i also didn´t find anything helpful on the internet can someone please help me

If you're doing this manually (say, for homework), think of the problem like this:
If you have a six character hex representation of a color ("7FD87F" for instance), it's made up of the RGB components R: 7F, G: D8, B: 7F.
Two hexadecimal digits can encode 256 different states (16^2 = 256), so each of these components is 8 bits in size (256 = 2^8).
You want to transform your value into a color space where each component is represented in 5 bits. The way to do this is to throw away the three least significant bits from each of the components. For example:
0b10101010 => 0b10101
As you correctly mentioned, you would do this via bit-shifting. You'll then need to recombine the components. As a hint, here's how I would recombine the original 8-bit components into a single 24-bit representation:
(R << 16) + (G << 8) + (B << 0)
# or just B since a shift by zero is equivalent to
# multiplying by 2^0 is
# multiplying by 1 is
# the multiplicative identity
So the sketch of your algorithm, assuming you are starting with a hex string and not an integer:
Split the hex string into individual color components
Convert the string representations to numeric representations
Bit shift the components
Recombine the 5-bit components into a 15-bit representation
Additionally, steps 1 and 2 are interchangible with some bit-masking and a little more bit-shifting.

Related

What purpose does .astype("uint8") have here?

(score,diff)= structural_similarity(original_gray,tempered_gray,full=True)
diff = (diff*255).astype("uint8")
print("SSIM:{}".format(score))
The above mentioned code is a snippet from a program that matches two images using their SSIM score. What I don't understand here is the function of .astype("uint8"), and why are we multiplying diff by 255?
Imagine a 2D array representing a greyscale (single channel) image. In general, the image data can come at you in one of two ways:
Pixel values are floats ranging from 0 to 1, or...
Pixel values are integers ranging from 0 to 255.
Occasionally you might also see levels expressed as percentages between 0 and 100, but that's basically the same as (1) above. Note that (2) can only express 255 grey levels, whereas (1) has almost arbitrary precision.
Sometimes you need (1) but have (2), or vice versa. Because software or preference or whatever.
To convert from (1) to (2) you must multiply by 255 and ensure that you have integers. In order to use the least amount of memory, you only need 8-bit integers, but those come in two flavours: signed (int8, ranging -128 to +127) and unsigned (uint8, ranging 0 to 255). For images you always want the unsigned kind.
To convert from (2) to (1) you can just divide by 255, making sure the result can hold floating point numbers of the desired precision.
So in your code, diff is being converted from a floating point image to an 8-bit one.

trouble with grabbing tag bits

I'm implementing a direct mapped cache using python which is direct mapped. Each line in cache contains 4 bytes. I'm having trouble for some reason with pulling out the first (in this case) 27 bits, and also the last 5 bits by using bit shifting.
I'm not sure what exactly I'm doing wrong in terms of bitshifting, but everything I've done is not giving me the desired bits I want. I'm doing a sort of "hard-coded" solution for now but converting the integer stored in cache to a bit string, and using python's string indexing to just get the first 27 bits, though I do want to know how to do it via bit shifting.
def getTag(d_bytes):
b = bin(d_bytes)
b = b[2:]
return (b[0:27])
Is the hard-coded solution I'm referring to.
If the value stored in cache is
0b11010101010101010000100010001
I would like to have a tag of:
110101010101010100001000 (The first 27 bits, as tag = (line size - index - offset)
An index of:
100 - next 3 bits following tag
and an offset of:
01 (The last two bits) - last two bits
You can extract the bits by masking and shifting.
To get the first n bits, the mask to use is 000011..(n times)..11. This mask can simply be generated with (1<<n)-1. This is equal to the number 2^n-1 whose code is exactly the mask that we want.
Now if you want to extract a bitfield that is at any position in your word, you have first to shift it right to the proper position, then use masking.
So for your problem, you can use
# extract n bits of x starting at position m
def getfield(x,n,m):
r=x>>m # shift it right to have lsb of bitfield at position 0
return r&((1<<n)-1) # then mask to extract n bits
lsb27=getfield(tag,27,0) # get bits x[26:0]
msb5=getfield(tag,5,27) # get bits x[31:27]

Python: mask/remove the least significant 2 bits of every 16-bit integer

I want to remove the least significant 2 bits of every 16-bit integer from a bitarray. They're stored like this:
010101**00**10010101101100**00**10101010.....
(The zeroes between the asterisks will be removed. There are two of them every 16 bits (ignoring the very first)).
I can simply eliminate them with a regular for loop checking indexes (the 7th and 8th after every 16 bits).
But... is there another more pythonic way to do this? I'm thinking about some slice notation or maybe comprehension lists. Perhaps I could divide every number by 4 and encode every one with 14 bits (if there's a way to do that).
You can clear bits quite easily with masking. If you want to clear bits 8 and 7 you can do it like this:
a = int('10010101101100',2)
mask = ~((1 << 7) | (1 << 8))
bin(a&mask)
more information about masking from here!

bitwise numbers python

I'm using tiled map editor to make 2d maps for making a game with pyglet. The tiles are numbered and saved to a .tmx file. The tiles numbers start at 1 and keeps ascending but when you flip a tile that tile number is changed with bitwise so when you parse the data you know how to flip it. The document explains how to break it down [here] (https://github.com/bjorn/tiled/wiki/TMX-Map-Format#data) under tile flipping. I have no idea where to even start, I've never used bitwise. I looked up bitwise for python and read about & | << >> bitwise operators and played with them in the interpreter but I still don't understand how to break down the tile numbers to get the data. One of the numbers I have is 2684354578 can someone show me how to do this?
The numbers are 32 bits wide. The upper 3 bits number 31, 30 and 29 identity the flipping information.
You can force these 3 bits to zero by expression
result = number & 0x1FFFFFFF
The prefix 0x means it is a hex number. Each digit represents 4 bits using the values 0 till 9 and A till F. The number is thus 3 zeros followed by 29 ones.

hex <-> RGB <-> HSV Color space conversion with Python

For this project I use Python's colorsys to convert RGB to HSV vice versa to be able to manipulate saturation and lightness, but I noticed that some colors yields bogus results.
For example, if I take any primary colors there's no problem:
However if I chose a random RGB color and convert it to HSV, I sometime gets bogus results.
Sometimes these bogus results occurs when I increase or decrease the lightness or the saturation of a color.
In this example lightness 10%, 20% and saturation 100% are bogus:
I'm not quite sure why it happens nor how I should fix this ..
The problem is in your dec2hex code:
def dec2hex(d):
"""return a two character hexadecimal string representation of integer d"""
r = "%X" % d
return r if len(r) > 1 else r+r
When your value is less than 16, you're duplicating it to get the value, in other words, multiplying it by 17. You want this:
def dec2hex(d):
"""return a two character hexadecimal string representation of integer d"""
return "%02X" % d

Categories