Remake for-loop to numpy broadcast
<p>I'm trying to code LSB steganography method via numpy arrays. I got code which makes the bool index mask, wich will give those bits of red channel, which need to xor with 1.</p>

<pre><code>import numpy as np
from scipy.misc import imread
import matplotlib.pyplot as plt

message = 'Hello, World!'
message_bits = np.array(map(bool, map(int, (''.join(map('{:b}'.format, bytearray(message)))))), dtype=np.bool)
img = imread('screenshot.png')
xor_mask = np.zeros_like(img, dtype=np.bool)
ind = 0 
for j, line in enumerate(xor_mask):
    for i, column in enumerate(line):
        if ind &lt; len(message_bits):
            xor_mask[j, i, 0] = message_bits[ind]
            ind += 1            
        else:
            break
    else:
        continue
    break         
img[xor_mask] ^= 1
</code></pre>

<p>Is there more compact way to construct the xor_mask? Maybe through numpy broadcast</p>

<p>UPD:
Reduced my for-loop to this:</p>

<pre><code>for j, line in enumerate(xor_mask):
    if ind &lt; len(message_bits):
        xor_mask[j, :, 0] = message_bits[ind]
        ind += len(xor_mask[j])
    else:
        break
</code></pre>

<p>If you pad <code>message_bits</code> to have as many elements as pixels in <code>xor_mask</code> then it gets simple:</p>

<pre><code>xor_mask = np.zeros_like(img, dtype=np.bool)
xor_mask[:, :, 0] = np.reshape(message_bits, xor_mask.shape[:2])
</code></pre>

<p>Another way, without padding:</p>

<pre><code>xor_mask[:, :, 0].flat[:len(message_bits)] = message_bits
</code></pre>

python numpy optimization scipy steganography