I notice we can set custom image model on wagtail here: https://docs.wagtail.io/en/v2.9/advanced_topics/images/custom_image_model.html
I am trying to add an automated focal point during upload max max 200*220px.
I tried a lot following its above documentation.
from django.db import models
from wagtail.images.models import Image, AbstractImage, AbstractRendition
class CustomImage(AbstractImage):
# Add any extra fields to image here
# eg. To add a caption field:
# caption = models.CharField(max_length=255, blank=True)
admin_form_fields = Image.admin_form_fields + (
# Then add the field names here to make them appear in the form:
# 'caption',
)
class CustomRendition(AbstractRendition):
image = models.ForeignKey(CustomImage, on_delete=models.CASCADE, related_name='renditions')
class Meta:
unique_together = (
('image', 'filter_spec', 'focal_point_key'),
Can anyone please help me get it done setting up custom focal point?
Thanks Anamul
You probably do not need a custom image
model to achieve this goal, Django has a built in system called signals
. This lets you listen to creation & editing (plus others) of any existing Django model and modify the data before it is saved to the DB.
A good example of this in use already in Wagtail is the feature detection system, which will automatically add a focal point on save if faces are detected.
You can see how this has been implemented in the source code, wagtail/images/signal_handlers.py.
You may need to understand how to build up a focal point, depending on how you want to calculate it but basically you need to call set_focal_point
on your image instance. This method must be supplied an instance of a Rect
which can be found in the source at images/rect.py
.
It is important to understand how to call your signal handlers registration function, I found this Stack Overflow answer to be helpful. However, it might be simpler to just add it to your wagtail_hooks.py
file as you know it will be run at the right time (when the app is ready & models are loaded.
You can read more at the Django docs for app.ready() if you would prefer not to rely on the wagtail_hooks.py
approach.
myapp/signal_handlers.py
from django.db.models.signals import pre_save
from wagtail.images import get_image_model
from wagtail.images.rect import Rect
def pre_save_image_add_auto_focal_point(instance, **kwargs):
# Make sure the image doesn't already have a focal point
# add any other logic here based on the image about to be saved
if not instance.has_focal_point():
# this will run on update and creation, check instance.pk to see if this is new
# generate a focal_point - via Rect(left, top, right, bottom)
focal_point = Rect(15, 15, 150, 150)
# Set the focal point
instance.set_focal_point(focal_point)
def register_signal_handlers():
# important: this function must be called at the app ready
Image = get_image_model()
pre_save.connect(pre_save_image_add_auto_focal_point, sender=Image)
myapp/wagtail_hooks.py
from .signal_handlers import register_signal_handlers
register_signal_handlers()