11

I need to import a bunch of images into a Django app. I am testing in the shell but cannot get past this error when attempting to save the image:

File "/lib/python3.3/codecs.py", line 301, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final) 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: 
invalid start byte

The model:

import uuid
from django.db import models
from taggit.managers import TaggableManager
import os

def generate_filename(instance, filename):
    f, ext = os.path.splitext(filename)
    name = uuid.uuid4().hex
    return 'images/%s%s' % (name, ext)

class StudyImage(models.Model):

    pic = models.ImageField(upload_to=generate_filename)
    upload_date = models.DateTimeField(auto_now_add=True)
    tags = TaggableManager()

The steps to get to the error:

Open a django shell.

import uuid
import os
from app import models

p = File(open('/home/image001.png', 'r'))
a = models.StudyImage(pic=p)
a.pic.save('test.jpg',p)

Which gives the error above. I cannot figure out why an image is giving a unicodecodeerror... I got this far referring to "Upload" a file from django shell

More details:

Django 1.7, Python 3.3

Full traceback:

Traceback (most recent call last):<br>
File "<input>", line 1, in <module><br>
File "/home/s/Pycharm/flf/venv/lib/python3.3/site-
    packages/django/db/models/fields/files.py", line 89, in save
self.name = self.storage.save(name, content)
File "/home/s/Pycharm/flf/venv/lib/python3.3/site-
    packages/django/core/files/storage.py", line 51, in save
    name = self._save(name, content)
File "/home/s/Pycharm/flf/venv/lib/python3.3/site-
    packages/django/core/files/storage.py", line 224, in _save
    for chunk in content.chunks():
File "/home/s/Pycharm/flf/venv/lib/python3.3/site-packages/django/core/files/base.py",
    line 77, in chunks
    data = self.read(chunk_size)
File "/home/s/Pycharm/flf/venv/lib/python3.3/codecs.py", line 301, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte
Community
  • 1
  • 1
Steve
  • 715
  • 10
  • 18
  • 2
    have you tried changing the line `p = File(open('/home/image001.png', 'r'))` to `p = File(open('/home/image001.png', 'rb'))`? – MBrizzle Jul 10 '14 at 00:40
  • I had not, regrettably! That was the problem. It seems that the 'r' and 'rb' settings work differently in Python 3 than in 2 - http://stackoverflow.com/questions/9644110/difference-between-parsing-a-text-file-in-r-and-rb-mode. @MBrizzle - if you add this as an answer I will accept. Thank you. – Steve Jul 10 '14 at 03:18
  • Yes the `rb` flag tells the file-handle to read the file as binary data, which is what you would do when opening an image, executables, etc. – Brandon Nadeau Jun 22 '15 at 00:21

1 Answers1

21

I'd been bit by this before, so I feel you -- but as per my comment: replace the 'r' with 'rb' in the File() call, and it should work fine.

I should also add, for those who come upon this answer later, that this is an issue specific to Python3. Take a look at the SO link in Steve's comment for a fuller explanation of the difference in File() between p2 and p3.

MBrizzle
  • 1,783
  • 1
  • 18
  • 31