django-imagekit
django-imagekit copied to clipboard
dynamically changing processors
I'm creating a mixin to generate a watermark
class ImageWatermarkModelMixin(models.Model):
watermarked_file = ProcessedImageField(
upload_to=watermarked_image_upload_to,
format='JPEG',
processors=[
ImageWatermark(
os.path.join(settings.STATIC_ROOT, 'momsplanner/images/watermark.png'),
position=('-7%', '-7%',),
repeat=False,
opacity=0.9,
)
],
max_length=200,
blank=True,
)
Now I want to change the watermark image ( os.path.join(settings.STATIC_ROOT, 'momsplanner/images/watermark.png') ) or scale factor for inheriting classes.
unfortunately ProcessedImageField doesn't accept processors which is callable.
So I'm trying to create a ProcessedImageField derived class to do this, but still hard because then I'd need to get a hold of current class or instance which uses the mixin that I'm creating.
Any idea how I can achieve this?
afk right now but there's a section on this in the docs.
ProcessedImageField are field, and ImageSpec is not a field right? which means, generated watermark won't be available for long (it might be cached but it has to be generated again)
Is there a way to use ImageSpec and persist the generated image?
It'll persist. Define a spec and use it in the field, with the spec kwarg.
Or the id kwarg like in the docs example.
Below is my implementation, but image is not wartermarked. I did get watermarked image when I supplied processors directly to the imagefield.
** edit ** nvm I didn't load the file to register the spec. :(
watermarked_file = ProcessedImageField(
upload_to=watermarked_image_upload_to,
max_length=200,
blank=True,
spec_id='watermark:ProductWatermark',
)
class WatermarkSpec(ImageSpec):
format = 'JPEG'
options = {'quality': 85}
@property
def processors(self):
+
+ return [
ImageWatermark(
self.get_watermark_path(),
**self.get_processor_params()
)
]
def get_watermark_path(self):
return os.path.join(settings.STATIC_ROOT, 'momsplanner/images/watermark.png')
def get_base_processor_params(self):
return {
'position': ('-35%', '-7%',),
'repeat': False,
'opacity': 0.9,
}
def get_processor_params(self):
return self.get_base_processor_params()
class ProductWatermarkSpec(BaseWatermarkSpec):
- def get_processor_params(self):
+ params = self.get_base_processor_params()
params.update({
'scale': 0.7
})
return params
register.generator('watermark:ProductWatermark', ProductWatermarkSpec)
And I tried passing spec kwargs, and I get
if spec_attrs:
if spec:
raise TypeError('You can provide either an image spec or'
' arguments for the ImageSpec constructor, but not both.')
error, because ProccessedImageField passes autoconvert=True always.
@littlehome-eugene Type error that you are seeing is because you are trying to pass spec_id and spec at the same time for your ProcessedImageField. They are used to do the same thing - pass a spac to use, but in different ways. You can't use both.
To clarify things at the end you want to have abstract model which has declared watermarked_file, but every concrete model extending your abstract one need to be able to change some of the parameters (watermark and scale) of the processor right?