55

UploadedFileをPILImageオブジェクトに変換Imageしてサムネイル化し、サムネイル関数が返すPIL オブジェクトをオブジェクトに変換しようとしていFileます。これどうやってするの?

4

7 に答える 7

108

ファイルシステムに書き戻さずにこれを行う方法として、open 呼び出しを介してファイルをメモリに戻すには、StringIO と Django InMemoryUploadedFile を使用します。これを行う方法の簡単なサンプルを次に示します。これは、「thumb」という名前のサムネイル画像が既にあることを前提としています。

import StringIO

from django.core.files.uploadedfile import InMemoryUploadedFile

# Create a file-like object to write thumb data (thumb data previously created
# using PIL, and stored in variable 'thumb')
thumb_io = StringIO.StringIO()
thumb.save(thumb_io, format='JPEG')

# Create a new Django file-like object to be used in models as ImageField using
# InMemoryUploadedFile.  If you look at the source in Django, a
# SimpleUploadedFile is essentially instantiated similarly to what is shown here
thumb_file = InMemoryUploadedFile(thumb_io, None, 'foo.jpg', 'image/jpeg',
                                  thumb_io.len, None)

# Once you have a Django file-like object, you may assign it to your ImageField
# and save.
...

さらに明確にする必要がある場合はお知らせください。私はこれを私のプロジェクトで現在作業しており、django-storages を使用して S3 にアップロードしています。ここで解決策を適切に見つけるのに、1日の大半を費やしました。

于 2010-12-28T07:55:03.760 に答える
14

私はこれをいくつかのステップで行う必要がありました。php の imagejpeg() には同様のプロセスが必要です。物事をメモリに保持する方法がないことは言うまでもありませんが、この方法では、元の画像とサムの両方へのファイル参照が得られます (通常は、戻ってサム サイズを変更する必要がある場合に適しています)。

  1. ファイルを保存します
  2. PILでファイルシステムから開き、
  3. PIL で一時ディレクトリに保存し、
  4. 次に、これが機能するように Django ファイルとして開きます。

モデル:

class YourModel(Model):
    img = models.ImageField(upload_to='photos')
    thumb = models.ImageField(upload_to='thumbs')

使用法:

#in upload code
uploaded = request.FILES['photo']
from django.core.files.base import ContentFile
file_content = ContentFile(uploaded.read())
new_file = YourModel() 
#1 - get it into the DB and file system so we know the real path
new_file.img.save(str(new_file.id) + '.jpg', file_content)
new_file.save()

from PIL import Image
import os.path

#2, open it from the location django stuck it
thumb = Image.open(new_file.img.path)
thumb.thumbnail(100, 100)

#make tmp filename based on id of the model
filename = str(new_file.id)

#3. save the thumbnail to a temp dir

temp_image = open(os.path.join('/tmp',filename), 'w')
thumb.save(temp_image, 'JPEG')

#4. read the temp file back into a File
from django.core.files import File
thumb_data = open(os.path.join('/tmp',filename), 'r')
thumb_file = File(thumb_data)

new_file.thumb.save(str(new_file.id) + '.jpg', thumb_file)
于 2010-09-16T02:53:05.717 に答える
10

これは、 python 3.5およびdjango 1.10の実際の動作例です。

views.py で:

from io import BytesIO
from django.core.files.base import ContentFile
from django.core.files.uploadedfile import InMemoryUploadedFile

def pill(image_io):
    im = Image.open(image_io)
    ltrb_border = (0, 0, 0, 10)
    im_with_border = ImageOps.expand(im, border=ltrb_border, fill='white')

    buffer = BytesIO()
    im_with_border.save(fp=buffer, format='JPEG')
    buff_val = buffer.getvalue()
    return ContentFile(buff_val)

def save_img(request)
    if request.POST:
       new_record = AddNewRecordForm(request.POST, request.FILES)
       pillow_image = pill(request.FILES['image'])
       image_file = InMemoryUploadedFile(pillow_image, None, 'foo.jpg', 'image/jpeg', pillow_image.tell, None)
       request.FILES['image'] = image_file  # really need rewrite img in POST for success form validation
       new_record.image = request.FILES['image']
       new_record.save()
       return redirect(...)
于 2016-09-26T18:41:41.123 に答える
1

これができるアプリがあります: django-smartfields

from django.db import models

from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor

class ImageModel(models.Model):
    image = fields.ImageField(dependencies=[
        FileDependency(processor=ImageProcessor(
            scale={'max_width': 150, 'max_height': 150}))
    ])

keep_orphans=True古いファイルを保持したい場合は、必ずフィールドに渡してください。そうしないと、置換時にクリーンアップされます。

于 2015-01-31T19:52:30.940 に答える