title: Python Encoding: Open/Read Image File, Decode Image, RE-Encode Image
body: <p>Note: I don't know much about Encoding / Decoding, but after I ran into this problem, those words are now complete jargon to me.</p>
  
  <p>Question:
  I'm a little confused here. I was playing around with encoding/decoding images, to store an image as a <code>TextField</code> in a django model, looking around Stack-Overflow I found I could decode an image from <code>ascii</code>(I think or binary? Whatever <code>open('file', 'wb')</code> uses as encoding. I'm assuming the default <code>ascii</code>) to <code>latin1</code> and store it in a database with no problems.</p>
  
  <p>The problem comes from creating the image from the <code>latin1</code> decoded data. When attempting to write to a file-handle I get a <code>UnicodeEncodeError</code> saying <code>ascii</code> encoding failed.</p>
  
  <p>I think the problem is when opening a file as binary data (<code>rb</code>) it's not a proper <code>ascii</code>encoding, because it contains binary data. Then I decode the binary data to <code>latin1</code> but when converting back to <code>ascii</code> (auto encodes when trying to write to the file), it fails, for some unknown reason.</p>
  
  <p>My guess is either that when decoding to <code>latin1</code> the raw binary data get converted to something else, then when trying to encode back to <code>ascii</code> it can't identify what was once raw binary data. (although the original and decoded data have the same length).
  Or the problem lies not with the decoding to <code>latin1</code> but that I'm attempting to ascii encode binary data. In which case how would I encode the <code>latin1</code>
  data back to an image. </p>
  
  <p>I know this is very confusing but I'm confused on it all, so I can't explain it well. If anyone can answer this question there probably a riddle master.</p>
  
  <p>some code to visualize:</p>
  
  <pre><code>&gt;&gt;&gt; image_handle = open('test_image.jpg', 'rb')
  &gt;&gt;&gt; 
  &gt;&gt;&gt; raw_image_data = image_handle.read()
  &gt;&gt;&gt; latin_image_data = raw_image_data.decode('latin1')
  &gt;&gt;&gt; 
  &gt;&gt;&gt; 
  &gt;&gt;&gt; # The raw data can't be processed by django 
  ... # but in `latin1` it works
  &gt;&gt;&gt; 
  &gt;&gt;&gt; # Analysis of the data
  &gt;&gt;&gt; 
  &gt;&gt;&gt; type(raw_image_data), len(raw_image_data)
  (&lt;type 'str'&gt;, 2383864)
  &gt;&gt;&gt; 
  &gt;&gt;&gt; type(latin_image_data), len(latin_image_data)
  (&lt;type 'unicode'&gt;, 2383864)
  &gt;&gt;&gt; 
  &gt;&gt;&gt; len(raw_image_data) == len(latin_image_data)
  True
  &gt;&gt;&gt; 
  &gt;&gt;&gt; 
  &gt;&gt;&gt; # How to write back to as a file?
  &gt;&gt;&gt; 
  &gt;&gt;&gt; copy_image_handle = open('new_test_image.jpg', 'wb')
  &gt;&gt;&gt; 
  &gt;&gt;&gt; copy_image_handle.write(raw_image_data)
  &gt;&gt;&gt; copy_image_handle.close()
  &gt;&gt;&gt; 
  &gt;&gt;&gt; 
  &gt;&gt;&gt; copy_image_handle = open('new_test_image.jpg', 'wb')
  &gt;&gt;&gt; 
  &gt;&gt;&gt; copy_image_handle.write(latin_image_data)
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
  &gt;&gt;&gt; 
  &gt;&gt;&gt; 
  &gt;&gt;&gt; latin_image_data.encode('ascii')
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
  &gt;&gt;&gt; 
  &gt;&gt;&gt; 
  &gt;&gt;&gt; latin_image_data.decode('ascii')
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
  </code></pre>