RFC: Removing CldImage 2-Stage Cropping & Resizing #432
Replies: 1 comment 8 replies
-
Great coverage on the issues and solutions! From what I can see the crop object seems to be the ideal solution. I think the key here will be the right documentation to help the consumer understand the mental model. The examples you have above are a good representation of the 2-stage flow. I wonder if the size can be derived from the CldImage props unless it's meant to be different. instead of redeclaring the size if it matches the CldImage: <CldImage
width="600"
height="600"
crop={{
width: 600,
height: 600,
crop: 'thumb',
source: true
}}
src="<Public ID>"
sizes="100w"
alt="Description of my image"
/> it would be: <CldImage
width="600"
height="600"
crop={{
crop: 'thumb',
source: true
}}
src="<Public ID>"
sizes="100w"
alt="Description of my image"
/> If the initial crop needs to be different or the user wants to be explicit, the values can be passed. <CldImage
width="600"
height="600"
crop={{
width: 1200,
height: 1200,
crop: 'thumb',
source: true
}}
src="<Public ID>"
sizes="100w"
alt="Description of my image"
/> Also, good tip about relative sizing for overlays. I definitely missed this.
|
Beta Was this translation helpful? Give feedback.
-
The goal of this document is to highlight current issues with the existing 2-stage cropping that occurs on the CldImage component and a proposed solution to resolve it.
Here's a video that also covers some of the below, I'd recommend reviewing both: https://res.cloudinary.com/colbycloud/video/upload/f_auto,q_auto/2024-02-16_12-27-12_r7vote.mov
Update Feb 22, 2024
Implemented and merged into beta via #431
Current Solution
The CldImage currently utilizes a 2-stage cropping and resizing process in order to provide an intuitive experience when working with the dynamic cropping and resizing methods that Cloudinary provides.
CldImage renders a Cloudinary URL, where in a basic example, we may serve an image "as is":
Because the CldImage component wraps the Next.js Image component, we can also opt into responsive sizing, so the scale of our image changes based on the size that is being generated by Next.js:
The important point to see here is the width of
828
which is automatically generated through the Next.js Image component. This is done by using a Loader function then generated using Cloudinary URLs.Another important point here is that the URL also contains 2 widths:
The goal here is to provide a "base canvas" for all images generated with responsive sizing for a consistent and intuitive experience.
To illustrate why this is important, we can start to add some transformations, such a simply a crop mode of "thumb":
These are two different image sizes that produce the same result.
However, the crop mode of "thumb" may produce different results if the crop is based on different sizes. We can see this in a modified example of the above:
The "thumb" cropping is being based on two different sizes, 1200x1200 and 600x600, producing different results, which in context of the CldImage component, would produce different results based on different sizes contained within the srcset:
Thus, the 2-stage sizing resolves this issue being able to first crop/resize the image on the "base layer" then provide the responsive sizing on a secondary stage.
The Problem
While this solves our problem of consistency, we create a big issue in our responsive sizing, in that the 1st stage results in a smaller sized image (usually) that may be smaller than the original.
The reason why this is important, is the 2nd stage that does the responsive sizing can no longer resize the image above the original size without distortion, as in the order of operations, the 1st stage sizes it down before other transformations are applied (such as the 2nd stage).
In the example of:
The image is first resized down to 1200, then further resized down to 640.
In the example of:
The image is first resized down to 600, but because we have already resized the image down to 600, we can no longer resized beyond that to 1200.
Proposed Solution
To avoid this, the first step is to get rid of the 2-stage cropping and resizing all together.
The default experience of CldImage would be that any transformations and effects would be based on the original image size and the responsive sizing would still apply after all transformations are made.
In one of the original examples of basic responsive sizing:
This is a simple example that really doesn't impact anything. Another such example could be using a crop mode of "fill", that performs a cropping transformation:
This works because no matter the image size, the image will fill the container.
Issue: Overlays & Relative Sized Transformations
The most obvious issue with removing the 1st stage cropping and resizing is that potentially all relatively positioned elements, such as text and image overlays, will now appear broken.
In an example with some basic text:
We can see the text is nice and large on the image, however when we remove the 1st stage:
The text is immediately smaller.
The solution here is to either resize the overlays or other relative sizing based on the new size:
Or define the object-based crop mode to set an initial base canvas similar to the original size, which would be the width and height defined on the CldImage top level props.
Issue: Dynamic Crop Modes
These first examples used crop modes that gracefully scale no matter the size, but what about a crop mode like "thumb"?
In our earlier example, we were trying to avoid differing sizes by using the 2-stage approach, where now, in the example:
We end up with different results.
To solve this, we can create an advanced way of utilizing the
crop
transformation by accepting an object that allows the user to specify a base width and height for the crop to be made on:This re-introduces the 2-stage cropping and resizing, but the differentiator is that it's user-defined and user opt-in.
It also allows the 1st stage, importantly, to specify the width and the height for the transformation to be based on.
While this isn't as easy as simply specifying
crop="thumb"
and it "just works", it's more reliable and doesn't sacrifice the experience and resolution of other transformations for this particular crop mode and other similar ones.To help alleviate this, we can provide a warning when the crop mode of thumb and other similar ones are used in conjunction with responsive sizing, as they can produce inconsistent results for visitors.
Beta Was this translation helpful? Give feedback.
All reactions