djangocms-frontend icon indicating copy to clipboard operation
djangocms-frontend copied to clipboard

Issue with Resizing Images to Larger Dimensions in Django CMS Frontend Plugin

Open JMSC11 opened this issue 1 year ago • 3 comments

Describe the bug When I upload a small image and try to set it to display at a larger size (upscale), the image does not respect the dimensions specified in the plugin settings or template. However, when I set a smaller size than the original, the resizing works perfectly.

To Reproduce Steps to reproduce the behavior: When adding an image using the Django CMS Frontend plugin, the dimensions for scaling the image are entered in the "Format" tab.

Screenshots Captura de pantalla 2024-12-02 010327

Desktop (please complete the following information):

  • OS: Windows
  • Browser Chrome

JMSC11 avatar Dec 02 '24 07:12 JMSC11

Hi @fsbraun ,

I am interested in working on this issue. Could you please assign it to me and provide some guidance?

baravkareknath avatar Mar 10 '25 09:03 baravkareknath

from PIL import Image

def resize_image(image, width, height, upscale=True):
    original_width, original_height = image.size

    # Allow upscaling only if explicitly enabled
    if not upscale and (width > original_width or height > original_height):
        width, height = original_width, original_height

    # Resize with high-quality resampling
    image = image.resize((width, height), Image.LANCZOS)
    return image

def get_size(self):
    """
    Returns the image size, allowing upscaling if enabled.
    """
    width, height = self.width, self.height
    image = Image.open(self.image.file)

    # Ensure upscaling is enabled for small images
    return resize_image(image, width, height, upscale=True)

baravkareknath avatar Mar 10 '25 09:03 baravkareknath

Could you please confirm if this code patch is correct and useful for resolving the issue? If it looks good, please let me know, and I will proceed with fixing the issue and submitting it.

baravkareknath avatar Mar 10 '25 09:03 baravkareknath

I was able to reproduce partially: upscaling and downscaling both work, BUT aspect ratio is maintained. This means, if for example you just want to resize on the height, but keeping the same width, the image will not resize. The bug is really just confusing UI.

A possible solution would be to make the UI clearer around the resizing. Perhaps adding a checkbox to say if you want to force the dimensions or keep the aspect ratio, and it would also help displaying the current image width and height in the input fields.

marbru avatar Oct 06 '25 10:10 marbru

I have been doing investigations on this bug during the last week. Here's my conclusions.

There is indeed a bug. But it is a nasty one because it comes from multiple interrelated causes rather than a single source.

The main culprit is that the code is delegating all image processing tasks to the easy_thumbnails library. More specifically, the scale_and_crop processor`: https://github.com/django-cms/djangocms-frontend/blob/main/djangocms_frontend/contrib/image/models.py#L105 The UI fields of width, height, crop and upscale match 1:1 to the options that that processor accepts. But here's the kicker: seems like that processor will not force dimensions in the images, but rather always preserve the aspect ratio (buy honoring the smaller dimension and autocalculating the other). Looking at the docs and code I could not find an option to override this behavior.

Most times this goes unnoticed, but causes strange behaviors in several places. For example:

  • scale_and_crop produces a resized image with dimensions that are different to the ones provided by the user. The html tags on the image do resize to the user dimensions, but sometimes they look like they have lost resolution (because image was made smaller by the thumbnailer, and then made bigger again by the html tags)
  • when the image is set to be "responsive" (which is active by default), then the bootstrap .img_fluid class is applied. Because this class applies height=auto, the provided html height tag is ignored, so the image only resizes to the specified user width.

The solution is not simple. The root fix would be to change the usage of easy_thumbnails to a different processor that would perform the resizing at file level honoring the dimensions. Or, if the behavior from easy thumbnails is actually preferred, we'd have to change the rest of the code around images, which at present I think assumes images are resized to the size provided by the user (ie: the leaking into html tags, the ui ...) - but this might be even trickier!

For now, I have made PR that updates the UI that does not fix the bug, but at least simplifies the image settings and makes their behavior clearer: https://github.com/django-cms/djangocms-frontend/pull/316

marbru avatar Oct 17 '25 11:10 marbru