A split image can't be merged after performing a .dot on any of the split bands using pillow/numpy
<p>I am trying to correct the color in images using pillow and numpy. Using im.split() in combination with np.array.</p>

<p>I would like to multiply all colours in the red band, but can't find a way of doing it.</p>

<p>I've tried all kinds of things and after a lot of googling had hoped that this would be the solution:</p>

<pre><code>from PIL import Image
import numpy as np

im=Image.open('test.jpg')
r,g,b=im.split() 

datar = np.array(r)
datag = np.array(g)
datab = np.array(b)

rm=0.4 # the value I would like to multiply all red pixels by

datar=datar.dot(rm) # this works, but turns the values in the array into floats
datar=datar.astype(int) # I was hoping this would solve it

im=Image.merge("RGB", (Image.fromarray(datar), Image.fromarray(datag), Image.fromarray(datab)))
</code></pre>

<p>I can do a lot of things with the arrays and the merge succeeds, but trying this gives me the following error:</p>

<pre><code>im=Image.merge("RGB", (Image.fromarray(datar), Image.fromarray(datag), Image.fromarray(datab)))
  File "/usr/local/lib/python2.7/dist-packages/PIL/Image.py", line 2408, in merge
im.putband(bands[i].im, i)
ValueError: images do not match
</code></pre>

<p>The array looks the same before and after the .dot and the .astype(int) are applied, and the values are multiplied correctly.</p>

<p><code>Image.merge</code> fails because rgb images are not of the same mode (see <a href="http://pillow.readthedocs.io/en/3.1.x/handbook/concepts.html#concept-modes" rel="nofollow">PIL Image modes</a>). You can check the mode this way:</p>

<pre><code>&gt;&gt;&gt; Image.fromarray(datar).mode
'I'
&gt;&gt;&gt; Image.fromarray(datag).mode
'L'
</code></pre>

<p>The reason for this is the type of the numpy array:</p>

<pre><code>&gt;&gt;&gt; datar.dtype
dtype('int32')
&gt;&gt;&gt; datag.dtype
dtype('uint8')
</code></pre>

<p>To fix that, replace this:</p>

<pre><code>datar=datar.astype(int)
</code></pre>

<p>with this:</p>

<pre><code>datar = datar.astype('uint8')
</code></pre>

python arrays python-2.7 numpy pillow