2012-02-19 42 views
9

Tôi đã tìm kiếm trên web cho câu hỏi của mình và không thể tìm thấy người trả lời rõ ràng cho bất kỳ ví dụ nào. Về cơ bản, tôi muốn sử dụng sorl và muốn thay đổi kích thước hình ảnh nguồn trong suốt thời gian tiết kiệm Model để thay đổi kích thước xuống kích thước 640x480, để tôi không lưu trữ các tệp 2.5 MB gốc của người dùng trên đĩa. Sau đó, tôi sẽ sử dụng templatetags để tạo hình thu nhỏ thông thường từ nguồn của tôi như được ghi trong sorl.Làm thế nào để thay đổi kích cỡ nguồn với hình thu nhỏ sorl?

Tôi đã gặp vài nguồn tham khảo sử dụng trường mô hình Hình thu nhỏ được cho là có sẵn trong sorl.thumbnail.fields. Xem liên kết here. Tuy nhiên, trong bản sao sorl cập nhật của tôi từ thân cây tôi không thấy bất kỳ ThumbnailField hoặc ImageWithThumbnailsField. Nỗ lực của tôi để nhập nó trong mô hình không phù hợp. Tôi thấy những tài liệu tham khảo này là cũ mặc dù và tự hỏi liệu tôi có thể đạt được cùng với sorl up-to-date.

Mặt khác, tài liệu sorl chỉ cho thấy ImageField từ sorl.thumbnail (xem here) mà không có bất kỳ đối số kích thước nào để kiểm soát thay đổi kích thước nguồn.

BTW, tôi thấy chức năng này có sẵn với easy_thumbnail có tham số đầu vào source_resize.

Mọi trợ giúp sẽ được đánh giá cao!

TÓM TẮT

tôi chấp nhận câu trả lời dưới đây, tuy nhiên tôi cảm thấy sự ủng hộ sorl tự nhiên đối với trường hợp sử dụng này có thể rất hữu ích - ví dụ: thêm resize_source param để ImageField sorl để cho phép thay đổi kích thước hình ảnh nguồn. Dưới đây là hai yếu tố lý do tại sao điều này có thể hữu ích trong trường:

  1. Không lưu trữ hình ảnh gốc lớn của người dùng nếu ứng dụng của bạn không cần. Tiết kiệm dung lượng đĩa.

  2. Không dành thêm CPU để thay đổi kích thước hình thu nhỏ từ các hình ảnh nguồn khổng lồ đó nếu bạn không có lý do cụ thể về chất lượng cao. Để tránh điều này có thể viết các thẻ lồng nhau trong các mẫu để thu nhỏ từ hình ảnh kích thước nhỏ hơn nhưng nó có thể trở nên khó chịu rất sớm.

+0

để bạn muốn người dùng tải lên hình ảnh được thay đổi kích thước thành chiều rộng và chiều cao có thể quản lý được __before__ áp dụng bất kỳ cây thu nhỏ nào? –

+0

Có, về cơ bản tôi muốn giữ cho các tập tin nguồn trên đĩa luôn luôn để phù hợp với hộp 640x480. – user1039384

+0

Tôi cảm thấy get_thumbnail sẽ giúp tôi làm điều đó - [ví dụ ở đây] (http://thumbnail.sorl.net/examples.html#model-examples). Tuy nhiên, tôi muốn ai đó xác nhận đây là trường hợp duy nhất cũng như đề xuất cách tốt nhất để đạt được điều này trong quá trình lưu ModelForm. Tôi có nên sử dụng ví dụ trước khi tạo tín hiệu hoặc tương tự để đạt được điều này? – user1039384

Trả lời

7

Sorl của ImageField mà bạn đề cập đến, chỉ là một Django bình thường ImageField với lợi ích bổ sung quản lý việc xóa thumbnails cache. Không có thay đổi kích thước được thực hiện trên lần tải lên ban đầu - đó là điều bạn phải tự thực hiện theo cách thủ công thông qua chế độ xem bạn đang sử dụng để tải lên. The docs show how to go about this. Bạn có thể sử dụng sorl trong rằng xem để làm các hoạt động thay đổi kích thước thực tế bản thân, sử dụng low level API examlpes

EDIT

Một thay thế nhanh hơn là để chỉ thay đổi kích thước hình ảnh khi model đang được lưu sử dụng sorl. Bạn có thể làm một cái gì đó như sau (hoàn toàn chưa được kiểm tra mặc dù!)

from sorl.thumbnail import get_thumbnail 

class Foo(models.Model): 
    image = models.ImageField(upload_to...) 

    def save(self, *args, **kwargs): 
     if not self.id: 
      # Have to save the image (and imagefield) first 
      super(Foo, self).save(*args, **kwargs) 
      # obj is being created for the first time - resize 
      resized = get_thumbnail(self.image, "100x100" ...) 
      # Manually reassign the resized image to the image field 
      self.image.save(resized.name, resized.read(), True) 
     super(Foo, self).save(*args, **kwargs) 

này sẽ có nghĩa là bạn sẽ có 2 phiên bản của cùng một hình ảnh trên đĩa - một trong những nơi mà các lĩnh vực hình ảnh django quyết định lưu nó (upload_to đường dẫn) và một nơi mà hình thu nhỏ sorl đã lưu hình thu nhỏ được thay đổi kích thước của nó. Điều này, cùng với thực tế là hình ảnh được tải lên và lưu lại hai lần, là những nhược điểm của phương pháp này.Việc triển khai nhanh hơn mặc dù

+0

Cảm ơn câu trả lời của bạn! Bạn có thể xây dựng trên các liên kết? Tôi tò mò muốn xem những gì nên được đề nghị cách làm nó. Nếu trong chế độ xem, tôi có nên lưu Mô hình của mình hai lần sau đó - một lần ban đầu thông qua lưu ModelForm, và sau đó lưu lại thể hiện trong dạng xem sau khi áp dụng phương thức mức thấp trên trường hình ảnh mẫu? – user1039384

+0

Lý tưởng nhất là bạn chỉ cần lưu một lần - bạn thực sự thay đổi kích thước tệp trước khi được lưu thay vì lưu, thay đổi kích thước và lưu lại. Đây là nơi phương thức 'handle_uploaded_file' có ích - đây là nơi tệp thực sự được lưu vào đĩa. Tôi sẽ thử thêm một ví dụ trong một phút –

+0

Vâng, rõ ràng, điều duy nhất mặc dù tôi tự hỏi liệu việc xử lý bản thân tải lên sau này sẽ ảnh hưởng đến việc chuyển sang bộ nhớ khác (nói S3) không? Đó là phần duy nhất giúp tôi tự hỏi liệu có nên xử lý nó hay để ImageField giải quyết nó và lưu thể hiện và sau đó cập nhật nó (mặc dù điều này cũng có chút xấu xí từ phối cảnh thực hiện nếu mọi thứ trên S3). – user1039384

2

Tôi đã tìm kiếm giải pháp một thời gian và cuối cùng đã viết ứng dụng django-resized.

+0

Đây là hình tôi đang tìm kiếm. Làm tốt lắm! –

12

Tôi đã tìm thấy lỗ hổng trong mã ở trên, có “str không có phương thức chunck()”, nếu ai đó muốn sử dụng nó. Đây là bản sửa lỗi của tôi:

from sorl.thumbnail import get_thumbnail 
    from django.core.files.base import ContentFile 

class Foo(models.Model): 
    image = models.ImageField(upload_to...) 


    def save(self, *args, **kwargs): 
     if not self.id: 
      super(Foo, self).save(*args, **kwargs) 
      resized = get_thumbnail(self.image, "100x100" ...) 
      self.image.save(resized.name, ContentFile(resized.read()), True) 
     super(Foo, self).save(*args, **kwargs) 
Các vấn đề liên quan