A bit of one of the pixel's RGB channels is extracted incorrectly. Steganography, LSB

There was a problem with extracting the last bit of the selected pixel channel. There is a program for steganography with the LSB algorithm that works. The meaning of the algorithm is that the character is divided into parts bitwise and written to the last bits of the image byte, that is, in rgb 1 pixel, second, etc. This is done sequentially in each color channel. I converted it to a specific RGB encoding. That is, the RGB spectrum is selected and only in it, skipping the others, the character bit is written. And it seems that there are no problems with packing the text into an image, but there are problems with extracting it. The extracted bit has always become 0. And the collected character is encoded to NULL according to the ASCII table.

Here is the Python code for decoding:

def decode_image(encoded_img, output_txt, symbols_to_read):
    img_mask = 0b11111110
    img_mask = ~img_mask
    print(bin(img_mask))
    img_len = os.stat(encoded_img).st_size
    selected_rgb = choose_rgb()

    if symbols_to_read >= img_len / 24 - BMP_HEADER_SIZE:
        print("Too much symbols to read")
        return False

    text = open(output_txt, 'w', encoding='utf-8')
    encoded_bmp = open(encoded_img, 'rb')

    encoded_bmp.seek(BMP_HEADER_SIZE + selected_rgb)

    read = 0
    while read < symbols_to_read:
        symbol = 0

        for bits_read in range(0, 8):
            img_byte = int.from_bytes(encoded_bmp.read(1), sys.byteorder) &\
                       img_mask
            symbol <<= 1
            symbol |= img_byte
            encoded_bmp.seek(2)

        if chr(symbol) == '\n' and len(os.linesep) == 2:
            read += 1

        read += 1
        print("Symbol #{0} is {1:c}".format(read, symbol))
        text.write(chr(symbol))

    text.close()
    encoded_bmp.close()
    return True


def choose_rgb():
    chosen_rgb = int(input("Choose a color spectrum to encode:\n1 - Red;"
                           " 2 - Blue; 3 - Green:\n"))
    return chosen_rgb - 1


to_read = int(input("How many characters are in the ciphertext?\n"))
image_file = "encoded.bmp"
decode_image(image_file, "result.txt", to_read)

In order to skip 2 spectra without encoded information, the value [0;2] was added to the bmp header to select the spectrum encoded_bmp.seek(BMP_HEADER_SIZE + selected_rgb) and then in the bit extraction cycle, 2 bytes are skipped by the method .seek() encoded_bmp.seek(2). I noticed that the problem occurs just in this place, when transferring the file pointer by 2 bytes. If you remove this line, everything works and the variable img_byte takes the actual values of the last bit other than 0.

Tell me, what is the error? It seems like everything should be correct, but something doesn't work at this point in the code.

for bits_read in range(0, 8):
            img_byte = int.from_bytes(encoded_bmp.read(1), sys.byteorder) &\
                       img_mask
            symbol <<= 1
            symbol |= img_byte
            encoded_bmp.seek(2)

And it seems that the problem occurs when moving the pointer over the bytes of the image. I don't understand why this is happening.
Let me remind you, when executing the code, due to the fact that img_byte always takes the value "0", NULL characters are generated and written to the file "result.txt" in the amount specified initially by the to_read variable. But if you extract a bit from each byte, then everything works correctly, the decoded text from the image is identical to the previously encoded one.

Author: Huginn, 2020-05-24