Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django先修改图像';它由stdimage处理_Python_Django - Fatal编程技术网

Python Django先修改图像';它由stdimage处理

Python Django先修改图像';它由stdimage处理,python,django,Python,Django,我正在使用django stdimage创建图像的变体 班级照片(models.Model): photo=StdImageField(上传至照片),详细名称=(“照片”), 变体={'large':(600600),'thumbnail':(100100)} StdImageField对图像执行自己的操作,对ImageField进行子类化,并具有attr\u class=StdImageFieldFile StdImageFieldFile执行实际的保存操作 类StdImageFieldFi

我正在使用django stdimage创建图像的变体

班级照片(models.Model):
photo=StdImageField(上传至照片),详细名称=(“照片”),
变体={'large':(600600),'thumbnail':(100100)}
StdImageField
对图像执行自己的操作,对
ImageField
进行子类化,并具有
attr\u class=StdImageFieldFile

StdImageFieldFile
执行实际的保存操作

类StdImageFieldFile(ImageFieldFile):
"""
与ImageFieldFile类似,但处理变化。
"""
def save(self、name、content、save=True):
super(StdImageFieldFile,self).save(名称、内容、保存)
render\u variations=self.field.render\u variations
如果可调用(渲染变量):
render_变体=render_变体(
文件名=self.name,
变量=自场变量,
存储=自存储,
)
如果不存在(渲染变量,布尔):
味精=(
“'render_variations'可调用需要一个布尔返回值,'
'但是得到了%s'
)%类型(渲染变量)
raise TypeError(msg)
如果出现以下情况:
self.render_变体()
但是,我想在StdImageFieldFile执行操作(旋转)之前对图像进行一些操作

因此,我创建了自定义字段,以便在图像传递到stdimage之前捕获它

类旋转(ImageFieldFile):
def save(self、name、content、save=True):
save=False
返回super(旋转、自)。保存(名称、内容、保存)
类StdImageFieldFileRotateMixin(Rotate,StdImageFieldFile):
通过
类StdImageFieldRotate(StdImageField):
attr_class=StdImageFieldFileRotateMixin

我有
旋转
类的
内容
属性中的图像,我可以使用PIL操作图像,但完成后,我不知道如何将此图像分配回内容属性。它似乎是在较低级别生成的。是否有方法生成此
内容
属性,然后再生成MRO w我将处理其余部分(即,将其传递给StdImageFieldFile,它将处理其余部分)

您可以将可调用的参数传递给
StdImageField
类的参数
render\u variations
,并在那里预处理图像

例如,假设您希望节省磁盘空间,并将原始映像调整为较小的版本,只将较小的映像与django stdimage创建的变体一起使用。您可以编写如下函数:

from io import BytesIO
from PIL import Image

from django.core.files.base import ContentFile

from stdimage.utils import render_variations

def preprocess(file_name, variations, storage):
    with storage.open(file_name) as f:
        with Image.open(f) as image:
            file_format = image.format

            # resize to a maximum of 1000x1000 keeping aspect ratio
            image.thumbnail((1000, 1000), resample=Image.ANTIALIAS)

            with BytesIO() as file_buffer:
                image.save(file_buffer, file_format)
                f = ContentFile(file_buffer.getvalue())
                # delete the original big image
                storage.delete(file_name)
                # save the resized version with the same filename and format
                storage.save(file_name, f)

    # render stdimage variations
    render_variations(file_name, variations, replace=True, storage=storage)

    return False  # prevent default rendering
class Photo(models.Model):
    photo = StdImageField(upload_to='photos', verbose_name=_("photo"),
                  variations={'large': (600, 600), 'thumbnail': (100, 100)},
                  render_variations=preprocess)
然后可以将函数传递给
StdImageField
类的
render\u variations
参数,如下所示:

from io import BytesIO
from PIL import Image

from django.core.files.base import ContentFile

from stdimage.utils import render_variations

def preprocess(file_name, variations, storage):
    with storage.open(file_name) as f:
        with Image.open(f) as image:
            file_format = image.format

            # resize to a maximum of 1000x1000 keeping aspect ratio
            image.thumbnail((1000, 1000), resample=Image.ANTIALIAS)

            with BytesIO() as file_buffer:
                image.save(file_buffer, file_format)
                f = ContentFile(file_buffer.getvalue())
                # delete the original big image
                storage.delete(file_name)
                # save the resized version with the same filename and format
                storage.save(file_name, f)

    # render stdimage variations
    render_variations(file_name, variations, replace=True, storage=storage)

    return False  # prevent default rendering
class Photo(models.Model):
    photo = StdImageField(upload_to='photos', verbose_name=_("photo"),
                  variations={'large': (600, 600), 'thumbnail': (100, 100)},
                  render_variations=preprocess)
这项技术的灵感来自Github上django stdimage项目自述文件中的

另外,在
preprocess
函数中处理图像的方式也受到了该方法的启发,并使用Django存储对象来处理图像文件的不同存储类型(想想Amazon S3)