This allows any file object to be used--even those that don't have a
`field` attribute. For example, you could theoretically use one spec
field as a source for another.
This marks a major step towards centralizing some of the "spec" logic
and creating a single access point for them. Because `ImageSpecFields`
are just alternative interfaces for defining and registering specs,
they can be accessed and overridden in the same manner as other specs
(like those used by template tags): via the spec registry.
Somewhere along the line, a change got merged that stopped using the
receivers module. This re-integrates it and moves changes made to the
old receivers (static methods on ImageSpecField) to them.
This new feature gives the user more control over *when* their images
are validated. Image cache backends are now exclusively for controlling
the *how*. This means you won't have to write a lot of code when you
just want to change one or the other.
Signals are now connected without specifying the class and non-IK
models are filtered out in the receivers. This is necessary because of
a bug with how Django handles abstract models.
Closes#126
While this change means users can no longer specify their own filenames,
changing a property of a processor, for example, will now result in a
new image. This solves a lot of the previous invalidation issues.
* develop:
IKContentFile accepts format hint
Additional mimetype utils
Don't get extension of empty filename
Tell people to import fields from the models module
Refactored AutoConvert into prepare_image
Docstring for save_image
Kill PIL's chattiness; fixes#91
PIL bug workaround
Use StringIO instead of temp file
Extract reusable save_image function
Rename SpecFile and move it to utils
Extract suggest_extension util from generator
Woah, globals
Add SpecFile.__unicode__
SpecFile is based after django.core.files.base.ContentFile, which lacks a __unicode__
method. This leads to an AttributeError when SpecFile.__repr__ is called. This is
easily resolved by giving SpecFile a proper __unicode__ method.
This extra layer of indirection allows us to tack some attributes
(name and content_type) onto the underlying file, which we cannot
do with a StringIO since it's a native ctype.
These attributes are used by various third-party software that expects
to work with django.core.files.File instances, and not directly with
StringIO instances. By way of example, the django-storages mosso
backend (CloudFilesStorage) looks for a content_type attribute, and
the cloudfiles Object backend looks for a name attribute.
[NEW] Processors: AddBorder
[NEW] Processors: Anchor has now its own class, taken from Crop
[CHG] Processors: Renamed Mat => ResizeCanvas, and will now use either
an anchor from Anchor or a user defined pixel offset
* matthewwithanm/whencontrol:
Rename cache_state_backend to image_cache_backend
Add NonValidatingCacheStateBackend
Some documentation
Only invalidate spec file if source changes
Rename DefaultCacheStateBackend
generate method (optionally) saves file
Rename force flag to force-revalidation
Add clear method for when future validation is unwanted
Commands for validating and invalidating the cache
Fix var name typo
Spec files now accessible through _ik attr
Remove unused import
First shot at cache state backend implementation
Conflicts:
imagekit/models/fields.py
`resize.Crop` actually hasn't been moved to `crop.Crop` (as the removed
class claimed). In fact, what used to be called `resize.Crop` is now
`resize.Fill`. The confusion is understandable, since it's what
motivated the change in the first place!
This way, there's a creation counterpart to `delete()`. The user
shouldn't have to deal with storage backends to create and delete the
files, and now they don't.
Though it's not the case with `FileSystemStorage`, attempting to delete
a nonexistent file can cause an exception (as in #80). We want to avoid
these errors but don't want to suppress others raised in the process of
deleting the file, so we first check to see if the file exists.
The `options` argument for `ImageSpec` and `ProcessedImageField`
replaces `quality` and provides a more general solution, allowing the
user access to PIL's format-specific options (including "quality",
"progressive", and "optimize" for JPEGs).
After #51 presented a good use case, we decided to make this part of
the API (i.e. remove the underscore). The default value for the `lazy`
kwarg is changed to `True` to reduce the likelihood of accidental
regeneration of images. Closes#54.
At first, we only had a small amount of code for preserving
transparency in `img_to_fobj`, but as that code grew it became apparent
that it really didn't belong in the utility function. This commit
creates an `AutoConvert` processor which is automatically run before
saving unless you disable it by passing `autoconvert=False` to your
`ImageSpec` or `ProcessedImageField` constructor. `img_to_fobj` is once
again a simple utility function for creating a file object from a PIL
image.
The in-code comments explain it pretty thoroughly but, in short, this
handles a lot more of the situations in which you're converting to or
from formats that support transparency.
Previously, we set it to an arbitrary large number (which turned out
not to be large enough in some cases). Since we may have been
overriding something the user explicitly chose (and our value may be
overridden by another app), that probably wasn't good. After this
change, `MAXBLOCK` is only increased when it needs to be--and even
then, only temporarily.
IK relies on PIL's EXTENSION list to map formats to extensions.
However, this list normally isn't populated until an image is loaded.
This change forces the population of the list before examining it.
* 'new_api' of https://github.com/matthewwithanm/django-imagekit: (63 commits)
fixing typo
ImageSpecFile is a proper File
Typo fix
A list of ImageSpec names are now stored on the model.
AdminThumbnailView is now AdminThumbnail
Docs typo fix
Adds explicit import of resize module to processors
fixing bad import in docs
adding name to AUTHORS
adding test for new api
Moved Crop and Fit to resize module.
More docs edits.
Typo fix.
Installation instructions.
Embracing duck typing.
Documentation!
Fix bug
Bound fields are now cached on the model instance.
Transpose processor now supports auto EXIF orientation.
Fix filename formatting.
...
Conflicts:
AUTHORS
README.rst
docs/Makefile
docs/conf.py
docs/index.rst
imagekit/__init__.py
imagekit/defaults.py
imagekit/management/commands/ikflush.py
imagekit/models.py
imagekit/options.py
imagekit/processors.py
imagekit/specs.py
tests/core/tests.py
Previously, ImageSpecFile was a file-like object, but didn't actually
extend any of the file classes. Because of this, some of Django's file-
handling code was duplicated. More importantly, instances didn't always
behave as one might expect (if one were familiar with ImageFields),
particularly when the source image was empty. This could have been
especially confusing in templates. (For example, because
ImageSpecFields whose source images didn't exist were still truthy.)
Previously, ImageSpecFile instances were retrieved (for saving and deleting,
among other possibilities) by iterating over the model instance's attributes.
This change adds ImageSpecFile names to a list (spec_file_names) on an
imagekit meta object on the model (_ik), making later retrieval much cheaper
and more straightforward.
I never liked that the "AdminThumbnailView" was supposed to be defined
on the model, but never looked into it.
This commit puts the definition back where it belongs: in the admin.
Instead of requiring you to add a field (with view logic) to your
model, you now just add a property to your admin class and specify
that property in the `list_display` list.
Crop doesn't necessarily imply the any scaling is taking place. Several
ideas were discussed, from renaming Crop to combining both processors
into a single Resize processor (as they were in the original IK), but
those solutions were felt to either precluded future extension
(alternative resize modes) or make the API too verbose.
ImageProcessor didn't do anything. I'd rather get it out of there to reduce the
temptation for future IK contributors to do type checking and mess up peoples'
custom processors.
Eric's fixes in c00ea10b0a meant that
some of the code that already existed to reuse objects would actually
be run for the first time. Naturally, there were some bugs; namely, I
was storing a filename (instead of a File object) in `_file` and a bad
else clause.
Replaced calls to Image.open with an open_image utility function.
The open_image utility calls Image.open, but then wraps the opened Image's
copy method with a version that preserves EXIF data. This allows an
ImageSpec to copy the original image, yet still provide all the original
image's exif data to the processor pipeline.
Centralized access of _img, tried to reduce re-calculation of some
properties, renamed _imgfield to source_file to reflect the fact that
it's an ImageFieldFile and not an ImageField.