Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

processingInstructions crop and cropVariant will be ignored #136

Closed
mediaessenz opened this issue Oct 30, 2019 · 6 comments
Closed

processingInstructions crop and cropVariant will be ignored #136

mediaessenz opened this issue Oct 30, 2019 · 6 comments
Assignees
Labels

Comments

@mediaessenz
Copy link

mediaessenz commented Oct 30, 2019

I seems, that the process instruction properties "crop" and "cropVariant" will be ignored completely.

I try to do something like this:

<f:variable name="records" value="{v:content.get(column:0, pageUid:123, limit:1, slide:'-1')}" />
<f:for each="{records}" as="record">
    <v:content.resources.fal field="image" as="images" record="{record}">
        <f:for each="{images}" as="image">
            <f:if condition="{image}">
                <pdf:image src="{image.id}" processingInstructions="{crop: image.crop, cropVariant:'default'}" width="100"/>
            </f:if>
        </f:for>
    </v:content.resources.fal>
</f:for>

Independent of any cropping inside the added images, they get not cropped.
If I add this debug output to the upper code right after the pdf:image:

<pdf:html>
    <pre>{image.crop -> f:debug(inline:1, plainText: 1)}</pre>
</pdf:html>

I get the correct settings array, which looks like this:

{
   "default":{
      "cropArea":{
         "height":1,
         "width":0.441,
         "x":0,
         "y":0
      },
      "selectedRatio":"NaN",
      "focusArea":{
         "x":0,
         "y":0,
         "width":0,
         "height":0
      }
   },
   "large":{
      "cropArea":{
         "x":0,
         "y":0,
         "width":1,
         "height":1
      },
      "selectedRatio":"NaN",
      "focusArea":{
         "x":0,
         "y":0,
         "width":0,
         "height":0
      }
   },
   "medium":{
      "cropArea":{
         "x":0,
         "y":0,
         "width":1,
         "height":1
      },
      "selectedRatio":"NaN",
      "focusArea":{
         "x":0,
         "y":0,
         "width":0,
         "height":0
      }
   },
   "small":{
      "cropArea":{
         "x":0,
         "y":0,
         "width":1,
         "height":1
      },
      "selectedRatio":"NaN",
      "focusArea":{
         "x":0,
         "y":0,
         "width":0,
         "height":0
      }
   },
   "extrasmall":{
      "cropArea":{
         "x":0,
         "y":0,
         "width":1,
         "height":1
      },
      "selectedRatio":"NaN",
      "focusArea":{
         "x":0,
         "y":0,
         "width":0,
         "height":0
      }
   }
}
@mediaessenz
Copy link
Author

mediaessenz commented Oct 30, 2019

After doing some research, I think the problem is the applyProcessingInstructions call inside the pdf:image viewhelper.
I think the overhanded processing instructions especial crop and cropVariant have to be transformed before they will work.
The call of this method ends in the process method of the LocalCropScaleMaskHelper class, which does somethink like this if a crop configuration is found:

$cropData = json_decode($configuration['crop']);
if ($cropData) {
    $crop = implode(',', [(int)$cropData->x, (int)$cropData->y, (int)$cropData->width, (int)$cropData->height]);
} else {
    $crop = $configuration['crop'];
}
list($offsetLeft, $offsetTop, $newWidth, $newHeight) = explode(',', $crop, 4);

This always results in "0,0,0,0", because the overgiven crop configuration is a multidimensional object with all crop variants, and not only the default one.
There is no cropVariant handling at all at this place.

Finally the type casting (int) in front of $cropData-> will convert all float values like "0.441" to 0.

Therefore the overgiven crop has to be converted from the upper format to something like this:

{
"height":100,
 "width":44,
 "x":0,
 "y":0
}

before they are overhanded to the applyProcessingInstructions call.

@maechler
Copy link
Member

maechler commented Oct 30, 2019

@mediaessenz You are absolutely right. I have to admit I never really tested crop variants and I thought that the image service will take care of it, but it does not.

A workaround would be to select the corresponding crop area yourself and pass it as crop attribute to the processingInstructions. The following code shows you a working example:

<f:variable name="crop" value="{default: {cropArea: {height:100,width:100,x:50,y:50}}}" />
<f:variable name="cropVariant" value="default" />
<f:variable name="cropArea" value="{crop.{cropVariant}.cropArea}" />
<f:variable name="cropString" value="{f:format.json(value: cropArea)}" />
<pdf:image processingInstructions="{crop: cropString}" src="EXT:pdfviewhelpers/Resources/Public/Examples/BasicUsage/Bithost.jpg" />

You probably just have to replace crop with image.crop. Does this work for you?

I will have to add a more user friendly support for crop variants to pdfviewhelpers however.

@maechler maechler self-assigned this Oct 30, 2019
@mediaessenz
Copy link
Author

mediaessenz commented Oct 30, 2019

Maybe something like this helps ;-)

if (!empty($this->arguments['processingInstructions'])) {
    $cropJson = $this->arguments['processingInstructions']['crop'];
    $cropVariant = $this->arguments['processingInstructions']['cropVariant'];
    if ($cropJson && $cropVariant) {
        $crop = json_decode($cropJson);
        if (property_exists($crop, $cropVariant)) {
            $cropSettingForImageServiceProcessing = new \stdClass();
            $selectedCrop = $crop->$cropVariant;
            $imageWidth = $imageFile->getProperty('width');
            $imageHeight = $imageFile->getProperty('height');
            $cropSettingForImageServiceProcessing->width = $selectedCrop->cropArea->width * $imageWidth;
            $cropSettingForImageServiceProcessing->height = $selectedCrop->cropArea->height * $imageHeight;
            $cropSettingForImageServiceProcessing->x = $selectedCrop->cropArea->x * $imageWidth;
            $cropSettingForImageServiceProcessing->y = $selectedCrop->cropArea->y * $imageHeight;
            $this->arguments['processingInstructions']['crop'] = json_encode($cropSettingForImageServiceProcessing);
            unset($this->arguments['processingInstructions']['cropVariant']);
        }
    }
    $processedImage = $this->imageService->applyProcessingInstructions($imageFile, $this->arguments['processingInstructions']);
}

@maechler
Copy link
Member

@mediaessenz Thanks for sharing your code! :)

@maechler maechler added the bug label Nov 6, 2019
@derhansen
Copy link
Contributor

Just for the records (and not related to processingInstructions, but to cropVariants). When using the pdf:html ViewHelper, it is possible to use the plain Fluid Image ViewHelper to render the crop variant of an image.

<pdf:html>
    <f:image src="{model.image.uid}" treatIdAsReference="1" cropVariant="your-crop-variant" width="500"/>
</pdf:html>

@maechler
Copy link
Member

I just released v2.3.4 which fixes this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants