matthewwithanm / django-imagekit

Automated image processing for Django. Currently v4.0
http://django-imagekit.rtfd.org/
BSD 3-Clause "New" or "Revised" License
2.26k stars 276 forks source link

Need official way to have thumbnails created and stored in database like ImageField when saving model #464

Open yybot1 opened 6 years ago

yybot1 commented 6 years ago

I think the cache strategy of ImageSpecField for thumbnails is complicated and error-prone, especially when using Imagekit with Django Rest Framework and external storage backend.

What I want is having several thumbnail fields in model, when uploading a file and saving model, thumbnails will be generated and saved as well.

Like the following, when photo uploaded, thumbnail fields should be automatically generated and saved.

class TestPhoto(models.Model):
    photo= models.ImageField(...)
    thumbnail_128 = models.ImageField(...)
    thumbnail_64 = models.ImageField(...)

there are tricks to do it with Imagekit (like #341 , #333), I use post_save to manually generate thumbnails and save them and it also works, but these tricks are ugly and not perfect.

I think it's good if there is an official way to do it with Imagekit, maybe as a new feature if needed.

vstoykov commented 6 years ago

The idea behind ImageKit is simple:

  1. A way to automatically resize an image during an upload time in order to not waste too much space on the server (ProcessedImageField)
  2. A way to automatically get thumbnail image from a source image stored in model (ImageSpecField, {% generateimage %}, {% thumbnail %})

The size of the thumbnails depends on design and design can change. If tomorrow you want differently sized images or with some effects applied, you simply change parameters in code (which can be in templates and not in models). When deployed the images will be automatically generated on first request. There is no need to store the thumbnail in the model when we have the source field.

Now for performance reasons some people decide to store the thumbnails in their database next to original image. ImageKit was not designed with this in mind. If someone is willing to try to implement it as a feature I will be very happy to review the work. It will conflict with the principles behind ImageKit but if this is what community wants - so be it.

If you think that the benefit to change any parameter of the thumbnail image at any time, without the need to run some custom migration which need to rebuild all images to match the new design (and until the migration finishes some parts of the site can look broken because images are not yet rebuild) outweighs the inconvenience of these custom migrations for rebuilding images, then we can look at better ways of using the ImageKit cache strategy.

I still think that the cache strategy of ImageKit can do a good job. Probably there need to be some improvements, especially around custom storage engines like S3 or other remote slow ones.

I'm open to concrete proposals with merge requests.

matthewwithanm commented 6 years ago

Listing the "complicated and error prone" things might be valuable. Maybe somebody could think of a better way to address them than what you've considered.

@vstoykov is running the show now but FWIW, I think of IK like this:

1) There's a source image in the database, with a backing file accessible via normal Django storage mechanisms. 2) There's a transformation defined in code (essentially a function from image -> image). 3) The transformation can be done at different points depending on preference (ahead of time, on demand, etc.) BUT 4) The timing of the transformation is decoupled from image access, which is done though normal idiomatic Django patterns (model fields and template tags) 5) Caching is used to get the best performance

If you want to generate the image immediately, that's what the cache file strategies are for—you shouldn't have to do manual post_save stuff.