Problem/Motivation

The current crop API is limited to only support one crop definition per image URI and crop type, while the crop type is the reference from the managed types (configuration).

What possibly seems obvious is not, or at least needs to be well documented and the user need to be aware of that fact.

If the same image is reused, the same crop definitions apply for all output.
What seems valuable (such reuse of a previously defined crop type for that image) makes sense if the image is considered a single resource and the individual crops are considered a focus on THE relevant aspect.
If i alter a crop definition when reusing the image, it also affects all other usages.
(We could check image usage and warn when cropping if it is already used.)
See issue for image_widget_crop: #2617820: Warn user on image reuse

However, if an image contains multiple objects that want to be referred and cropped individually, we can not deal with the situation. The only thing we could do is clone the original resource.

Examples:
- If a node has a gallery and we want to select multiple detail zoom crops from a total image (same document, same field, different delta)
- If a node has multiple fields and want to use different croppings of the same original (same document, different fields)
- If an image is browsed by entity browser and picked for a second time.

Proposed resolution

Crop should be clear that the current setup of the crop definitions are currently more a composite of the file entity with reference through URI.

Supporting variants can no more happen that easily through the same image style definition, because a file is only rendered and delivered once.
Instead to support variants, we need to:
- Replace the image formatter, because the image URL is different and has new context
- Provide an alternative crop schema / route to render the variants that eats entity type, entity id, field name, delta
-- Load the original image based on the placement context

I realise that with this approach we could use the URI of the image placement to save crop data.

Remaining tasks

Discuss and decide if this kind of variations should be supported.
If yes, then document how the variants would be supported.
Decide about how we will document it, and do it. ;-)

User interface changes

API changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

miro_dietiker created an issue. See original summary.

miro_dietiker’s picture

Issue summary: View changes
miro_dietiker’s picture

Title: Support crop variants per URI and crop type » Support multiple crop variants per URI and crop type
woprrr’s picture

Issue tags: +D8Media

Bad comment It's not iwc issue :o !

slashrsm’s picture

Issue tags: +Media Initiative

This is a tough one. Implementation of image styles is mostly responsible for that as it has no other context information other than URI. That is also main reason why I designed Crop API in a way it is (crop ends up being tied to URI at the end). I'd much rather related it to something that makes more sense, but that is currently not possible.

I agree first step is to make people aware of this. Then we should think if we can solve this in a better way. I am afraid though, that we won't be able to do this w/o changing core.

esolitos’s picture

I'll joins this discussion. :)
I do totally believe that the crop data should be stored "per field basis", meaning every time you use an image field you should be able to define a new crop.

Obviously when using the simple "image upload" (and similar) widget this is not a problem, because you will every time upload a new image which will have it's own URI, however we all know that a website of a decent complexity/size will probably use things like File Browser, which allows to re-use a file multiple times. In this occasion you might want use the same image with different image cropping based on it's usage.

I was suggested by @woprrr to use Entity Clone on the fiels and apply the new crop of the cloned image, this of course is a decent workaround, but I do believe that it's not a solution.

The question is: how do we go from here?

esolitos’s picture

Priority: Normal » Major

PS: I believe that his is Major, correct me if I'm wrong, but it's an important feature that, if absent, makes crop-api not so usable in may scenarios.

miro_dietiker’s picture

You could even claim it critical for cases that don't agree with the current situation.

It's more a documenation of a fact in the current architecture of Crop API, by following core patterns.

The limiting problem is:
Core does not allow us the same image to have multiple URLs based on multiple placements.

Supporting multiple in the current core behavior means one of the items:
- Make a core feature request to allow us to modify an image path based on the placement.
- Reimplement image delivery, leading to alternative delivery routes and image formatters and duplicate redefinition of many formatters building on top of it.

I'm open to hear about how we can plug into the situation and make the image URL vary based on the current placement context.

esolitos’s picture

Hello, I didn't had time to follow up this discussion after my last post, is there any progress in this direction or should this be considered a "lost cause" due to the described limitations?

slashrsm’s picture

This would require quite big core change in image styles area. There are no plans for activity on this issue in the foreseeable future.

esolitos’s picture

Status: Active » Postponed

I see, thanks for the info.
I'll go ahead and mark as postponed, who knows maybe one day it will be possible.

miro_dietiker’s picture

I understood "Postponed" needs a reference to a reason, typically an issue that is still open. Otherwise it's more a won't fix.

So is there a core issue we can refer to?

While we are not working on it, i get asked again and again about it and people claim it's a real use case.
But also, when investigating, i found out that many DAMs simply offer quick cloning of resources through UI to resolve this problem. That might be the most practical solution! We could even keep/populate a reference to the original if the entity offers a reference field with this purpose.

What do you think?

kristougher’s picture

In the D7 module Crop Entity https://www.drupal.org/sandbox/kristougher/2423063 we have created a solution where the cropping of an image spawns a crop file entity with the cropped image as URI. The relation is saved in a separate table.

Before rendering the entity with the image, the crop relation is located and the image uri is replaced with that of the crop entity.

It is a slightly blunt way of achieving this, but we have had clients to whom it was absolutely mandatory to have this feature. And it is being used in production on several sites.

woprrr’s picture

Assigned: Unassigned » woprrr
Status: Postponed » Needs work

I will go ahead and assign myself the synchronization around this major problem. I will take note of all the possibilities advanced by @miro and decide here an MVP around the possibility of obtaining satisfaction and see what really blocks us. The presence of reusable in-core media could greatly simplify our problems, but we must be careful not to abandon File (File Entity) users or other non-Media in core use cases. Let us try to define what are the critical functions and needs to achieve our ends. The idea of ​​the relationship (field) I like a lot personally it is close to the approach paragraphs?

EDIT :

            'cid' => $crop->fid,
            // We will add delta in element_name to support multiple cardinality ?
            'parent_element_name' => $referencing_entity_loaded,
            'parent_type' => (EntityType or FormState ?)
            'parent_id' => $EntityIdOfParent
            'original_file_uri' => $crop->getOriginalFileUri(),
            'bundle' => $cropType,

If we add this previous parameters we can be able to contextualize correctly ?

woprrr credited Berdir.

woprrr credited marcoscano.

woprrr’s picture

seanB’s picture

Some thoughts after discussing this with woprrr on slack:

I think that is the main issue is you need the generate a different image for the same file URI based on a "context" that we currently do not store anywhere. To solve this, Crop API should introduce the concept of "contexts" for images. A contexts could be based on the relation to the parent entity for example.

For media however, the concept of "contexts" becomes more difficult, since a file/image is only directly tied to 1 media item. So then you will probably need something like entity_usage to figure out the relations of the media item and create "contexts" for the file for each relevant relation.

If you want to use a different crop per node for example, you need to store the node > media > file relation as a "context" for the file and make the image styles use the right context when generating an image. This becomes even more difficult when you have something like node > paragraph > paragraph > media > image.

So, at the moment, I don't think this is a problem for drupal core and if this needs to be solved it would probably need to be done by the Crop API by implementing "contexts" and overriding the relevant parts of image styles to work with this.

candelas’s picture

@woprr did you have time to take a look into this? I am building a site and this is a major issue. Thanks :)

rang501’s picture

Hi!
Any news on this? I have multiple sites which need this.

DrDam’s picture

Hi!
Any update on this? Same as rang501, I need this for many projects

anruether’s picture

> If you want to use a different crop per node for example, you need to store the node > media > file relation as a "context" for the file and make the image styles use the right context when generating an image. This becomes even more difficult when you have something like node > paragraph > paragraph > media > image.

This sounds like this would benefit from #2904842: Make private file access handling respect the full entity reference chain (see also Media Private Access | Drupal.org)

anruether’s picture

trackleft2’s picture

In DAM speak, I believe this concept is called "rendition" In the context of Digital Asset Management, rendition means different editions or versions of an original asset, for example, an alternative file format, color space or resolution.

The use of the expression 'version' can be confusing to understand for those new to DAM. In terms of relationships with assets, Renditions are adjacent to assets rather than having any chronological or sequential meaning. Each version of an asset might itself have multiple renditions generated at the time that version was created.

Alternative terms for rendition are derivative files, proxies or surrogates. Rendition has a broader based usage than some of these (proxy especially) and can also describe the process of generating variations to underlying assets.

https://damglossary.org/Rendition

beerendlauwers’s picture

The experimental Media Library Media Modify module appears to add support for #24. Now we need a patch to actually implement an override for the crop per media item.

junaidpv’s picture

Please have a look on "Crop Image" module we created while back to work around this problem.

DrDam’s picture

In response of #26 :

I have create a patch on the module permitting save some override data for crop : here
patch : https://www.drupal.org/files/issues/2022-06-01/manage_crops_3270150-5.patch

How use it :

I Just add a little alter in getOverriddenValues method.

        // Alter referenced_entity_values
        \Drupal::moduleHandler()->alter("media_library_media_modify_referenced_entity_values", $referenced_entity_values, $field_name, $referenced_entity);

with this, other module like "focal_point" can just "add" there data to the overridden data like :

function focal_point_media_library_media_modify_referenced_entity_values_alter(&$values, $field_name, $referenced_entity ) {

  $item_list = $referenced_entity->get($field_name);

  foreach($item_list->getValue() as $key => $item) {
      if(isset($item['focal_point'])) {
        $values[$key]['focal_point'] =  $item['focal_point'];
      }
    }
}

Remaining problem

The problem persist, because crop (like other Image effects) are applied when the derivative is generate.

At this moment, there is no way to know where image come from ( the image are referenced by a media, itself referenced by a node, where crop information are overrided). Without this information, there is no way to get back the overrided data.

Proposed solution

One solution may be to add a "context" field in crops (as woprr propose), and alter image path generation to add a hash of the context (or alter generative path to represent the context)

During the generation of derivative,
IF a hash are present and correspond to a context => the corresponding crop must be used
Else we stay on "standard" detection (by uri & crop type)

With this process :
- standard crop (on stand alone image or basic media configuration) stay as current (with empty context)
- overrided need can be passed through specific input (like proposed with patch on #3023807-5: Override media fields from the reference field or core #3023807: Override media fields from the reference field).
This input create a new entity with a specific context

The last (but really big) point are the core image derivative system which not permiting generate multiple derivative from a same source with the same imageStyle.

DrDam’s picture

Hi everyone,

In conclusion about my message of the last week, I have develop a module dealing with that : multi_crop

like @beerendlauwers, the idea are to use the work made by media_library_media_modify for the "media local alteration (waiting core #3023807: Override media fields from the reference field), and deal with core_image_styling limitation (I assume there is a dirty work here).

The two crop widget are managed !

DrDam’s picture

Hi all, just an update here.

The module "multi_crop" is now deprecated and replace by media_contextual_crop suite now fully Drupal 10 compatible.

The suite are compose with 5 modules :
- media_contextual_crop : as the core-api module
2 use_case modules ;
- media_contextual_crop_embed : for croping media in ckeditor (4 & 5)
- media_contextual_crop_field_formatter : for cropping in media reference fields
2 crop plugin adapters :
- Focal Point adapter
- Image Widget Crop adapter : for cropping in media reference fields

DrDam’s picture

Version: 8.x-1.x-dev » 8.x-2.x-dev
FileSize
1.9 KB

Hi,

I'm still working on the subject (get multiple crop on a single media), and I've just modified the approach of my solution.
Until now (on version 1.x of the media_contextual_crop suite), I had to duplicate the image source in order to stay within the standards of image generation by ImageStyle and the Crop_API module.

For version 2.x of the media_contextual_crop suite (nearly released), I'd like to do away with the need to duplicate sources, and to do so I need to store a context in the CROP entity itself.
The patch I'm proposing goes in this direction.

The "retrieval" part of the context ( in the findCrop method) still needs to be fine-tuned.

DrDam’s picture

Just an update of the patch, in order to fix conflict between overrided and non-overided usages

DrDam’s picture

@woprr, @miro_dietiker :

Stop me if I say something stupid. It seems, the subject of the issue concerns two different aspects.

1- The "re-usage" of image (I.E. using media entities reference fields instead of image fields.
In reality, the point should cover all cases where the image file is carried by an "intermediate entity", not just media.
This case have it's own issue #2983622, and the media_contextual_crop suite address only the "media case".

2- The couple "Image-Crop Type" which are more restrictive than the "core Image-style" couple (in the image-styling process).
This case (I think it's the original subject of the issue) are if you use a CropType (ex : 16:9) in multiple styles ( large_16_9 , tiny_16_9), the implementation of the CROP Entity DOES NOT ALLOW to define two "crop settings" for the same image (one for each style). Maybe this is a "non-use-case", so nothing to say about.

PS :In order to keep this debate cleaner, I propose to move my comments about the media_contextual_crop suite to #2983622 (if @woprr re-open it)