Example #1
0
def _lsb_dct_coefficient_encode(image, output, message, nbits=1):
    assert len(image.quantization) * 64 >= len(message) * 8

    bit_mask = (1 << nbits) - 1
    msg_iter = iter_bits(message, nbits)
    for i in range(len(image.quantization)):
        for j, msg_bit in zip(range(64), msg_iter):
            image.quantization[i][j] = (image.quantization[i][j] & ~bit_mask) | msg_bit
    image.save(output, qtables=image.quantization)
    return image
Example #2
0
 def test_iter_bits_double(self):
     # Try comparing chunks returned by iter_bits (when chunksize=2)
     # to string returned by bin() using capital letters
     # e.g. 'A' == 65 == 0b1000001
     #      iter_bits('A', chunksize=2) == [01, 00, 00, 01]
     for o in range(65, 91):
         char = chr(o)
         bits = list(iter_bits(char, chunksize=2))
         exp_bin_str = '{:08b}'.format(o)
         bin_str = self._bin_str_from_chunks(bits, chunksize=2)
         self.assertEqual(bin_str, exp_bin_str)
Example #3
0
 def test_iter_bits_single(self):
     # Try comparing bits returned by iter_bits to string returned
     # by bin() using capital letters from the alphabet.
     for o in range(65, 91):
         char = chr(o)
         bits = list(iter_bits(char))
         while bits[0] == 0 and len(bits) > 1:
             # bin() drops leading zeros
             bits.pop(0)
         bin_str = '0b' + ''.join(map(str, bits))
         self.assertEqual(bin_str, bin(o))
Example #4
0
def _lsb_pixel_encode(image, output, message, nbits=1):
    assert fits_in_image(image, message, nbits)

    # TODO: can this be accomplished with Image.tobytes/frombytes/BytesIO or ImageChops with a dummy message Image
    # Encode nbits of the message into each of the three color-components (RGB)
    # for each pixel until we're at the end of the message.
    # The bit mask needs to capture the least nbits significant bits.
    pixels = image.load()
    bit_mask = (1 << nbits) - 1
    msg_iterator = grouper(iter_bits(message, chunksize=nbits), 3)
    for xy, msg_part in zip(iter_coords(image), msg_iterator):
        rgb = tuple((component & ~bit_mask | chunk) if chunk is not None else component
                    for component, chunk in zip(pixels[xy], msg_part))
        pixels[xy] = rgb
    image.save(output)
    return image