想创建在Django的缩略图,我试图专门建立一个自定义类用于生成缩略图。作为继
from cStringIO import StringIO
from PIL import Image
class Thumbnail(object):
SIZE = (50, 50)
def __init__(self, source):
self.source = source
self.output = None
def generate(self, size=None, fit=True):
if not size:
size = self.SIZE
if not isinstance(size, tuple):
raise TypeError('Thumbnail class: The size parameter must be an instance of a tuple.')
# resize properties
box = size
factor = 1
image = Image.open(self.source)
# Convert to RGB if necessary
if image.mode not in ('L', 'RGB'):
image = image.convert('RGB')
while image.size[0]/factor > 2*box[0] and image.size[1]*2/factor > 2*box[1]:
factor *=2
if factor > 1:
image.thumbnail((image.size[0]/factor, image.size[1]/factor), Image.NEAREST)
#calculate the cropping box and get the cropped part
if fit:
x1 = y1 = 0
x2, y2 = image.size
wRatio = 1.0 * x2/box[0]
hRatio = 1.0 * y2/box[1]
if hRatio > wRatio:
y1 = int(y2/2-box[1]*wRatio/2)
y2 = int(y2/2+box[1]*wRatio/2)
else:
x1 = int(x2/2-box[0]*hRatio/2)
x2 = int(x2/2+box[0]*hRatio/2)
image = image.crop((x1,y1,x2,y2))
#Resize the image with best quality algorithm ANTI-ALIAS
image.thumbnail(box, Image.ANTIALIAS)
# save image to memory
temp_handle = StringIO()
image.save(temp_handle, 'png')
temp_handle.seek(0)
self.output = temp_handle
return self
def get_output(self):
self.output.seek(0)
return self.output.read()
类的目的是这样我就可以使用它不同的地点里面动态生成缩略图。该类完美工作,我已经直接在视图下进行测试..我已经在窗体的保存方法中实现了缩略图类,以在保存时调整原始图像的大小。
在我的设计中,我有两个缩略图字段。我能够生成一个缩略图,如果我尝试生成两个它的崩溃,我已经被困了几个小时,不知道是什么问题。
这里是我的模型
class Image(models.Model):
article = models.ForeignKey(Article)
title = models.CharField(max_length=100, null=True, blank=True)
src = models.ImageField(upload_to='publication/image/')
r128 = models.ImageField(upload_to='publication/image/128/', blank=True, null=True)
r200 = models.ImageField(upload_to='publication/image/200/', blank=True, null=True)
uploaded_at = models.DateTimeField(auto_now=True)
这里是我的形式
class ImageForm(models.ModelForm):
"""
"""
class Meta:
model = Image
fields = ('src',)
def save(self, commit=True):
instance = super(ImageForm, self).save(commit=True)
instance.r128 = SimpleUploadedFile(
instance.src.name,
Thumbnail(instance.src).generate((128, 128)).get_output(),
content_type='image/png'
)
instance.r200 = SimpleUploadedFile(
instance.src.name,
Thumbnail(instance.src).generate((200, 200)).get_output(),
content_type='image/png'
)
if commit:
instance.save()
return instance
奇怪的部分是,当我删除其中包含的形式保存instance.r200行。它工作正常,它会缩略图并成功保存。一旦我添加第二个缩略图失败..
任何想法是什么做错了吗?
感谢
更新:
按照评论的请求,我追加错误跟踪
IOError at /en/publication/new/
cannot identify image file
Request Method: POST
Request URL: http://127.0.0.1:8000/en/publication/new/?image-extra=
Django Version: 1.4.2
Exception Type: IOError
Exception Value:
cannot identify image file
Exception Location: /Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/PIL/Image.py in open, line 1980
Python Executable: /Users/mo/Projects/pythonic/snowflake-env/bin/python
Python Version: 2.7.2
更新
尝试创建print语句和下面是输出
Source: publication/image/tumblr_m9o7244nZM1rykg1io1_1280_11.jpg
Source: publication/image/tumblr_m9o7244nZM1rykg1io1_1280_11.jpg
ERROR:root:cannot identify image file
ERROR:django.request:Internal Server Error: /en/publication/new/
Traceback (most recent call last):
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 20, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/db/transaction.py", line 209, in inner
return func(*args, **kwargs)
File "/Users/mo/Projects/pythonic/snowflake-env/snowflake/snowflake/apps/publication/views.py", line 69, in new
formset.save()
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/forms/models.py", line 497, in save
return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/forms/models.py", line 628, in save_new_objects
self.new_objects.append(self.save_new(form, commit=commit))
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/forms/models.py", line 727, in save_new
obj = form.save(commit=False)
File "/Users/mo/Projects/pythonic/snowflake-env/snowflake/snowflake/apps/publication/forms.py", line 113, in save
Thumbnail(instance.src).generate((200, 200)).get_output(),
File "/Users/mo/Projects/pythonic/snowflake-env/snowflake/snowflake/apps/core/utils.py", line 23, in generate
image = Image.open(self.source)
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/PIL/Image.py", line 1980, in open
raise IOError("cannot identify image file")
IOError: cannot identify image file
如图所示,第一张图像被打印并成功处理,第二张图像失败。在缩略图类应用副本()后
更新
追踪误差更新
ERROR:root:cannot identify image file
ERROR:django.request:Internal Server Error: /en/publication/new/
Traceback (most recent call last):
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 20, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/db/transaction.py", line 209, in inner
return func(*args, **kwargs)
File "/Users/mo/Projects/pythonic/snowflake-env/snowflake/snowflake/apps/publication/views.py", line 69, in new
formset.save()
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/forms/models.py", line 497, in save
return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/forms/models.py", line 628, in save_new_objects
self.new_objects.append(self.save_new(form, commit=commit))
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/django/forms/models.py", line 727, in save_new
obj = form.save(commit=False)
File "/Users/mo/Projects/pythonic/snowflake-env/snowflake/snowflake/apps/publication/forms.py", line 113, in save
f128.write(Thumbnail(instance.src).generate((128, 128)).get_output())
File "/Users/mo/Projects/pythonic/snowflake-env/snowflake/snowflake/apps/core/utils.py", line 15, in __init__
self._pilImage = Image.open(self.source)
File "/Users/mo/Projects/pythonic/snowflake-env/lib/python2.7/site-packages/PIL/Image.py", line 1980, in open
raise IOError("cannot identify image file")
IOError: cannot identify image file
更新
最后,我设法得到它的工作,但我必须将该文件传输到self.source中,因为belo
def __init__(self, source):
self.source = StringIO(file(source.path, "rb").read())
self.output = None
self._pilImage = Image.open(self.source)
是上述理想方法吗?在每次击中时阅读文件是个好主意吗?如果不是,我有什么选择?
P.S得到的错误是“无法识别图像文件” –
您有没有原因使用['django-stdimage'](http://code.google.com/p/django-stdimage/)? –
不使用stdimage的原因是因为我的裁剪图像不仅仅是在重新生成..我不知道重复,我认为它与缩略图类有关。 –