Image cropping

Great feature of TYPO3 is dynamic work with images. The developers can specify image sizes directly in template and don’t need any other workouts. But what’s moving this option on another level is the possibility to choose in backend a viewport for multiple variants at the same time.

Classic example is a full screen hero. You have to upload multiple images to not to break the main motive, because of difference between mobile (portrait view) and 2k desktop (large landscape). 

Customer: Where is the baloon on my phone?

Next example is also very known. In news listing you have designed images in ratio 16:9. Editors upload image 1:1 and then complain that a person in the picture has cut head, but there is a large space under his legs.

Now I would show you my image practice. 

Prepare crop variants

The crop variants are connected mostly to the sys_file_reference table, so we would overwrite this table configuration.

First we have to define some basic ratios, like square (1:1) and the classic 2:3, 3:4 and 16:9 or some others if we have special usage.

//typo3conf/ext/boilerplate/Configuration/TCA/Overrides/sys_file_reference.php

$allowedRatios = [
    'NaN' => [ // Free mode - ignore all ratios, you can select area that you like
        'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.ration.nan',
        'value' => 0.0
    ],
    '1:1' => [
        'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.ration.1_1',
        'value' => 1
    ],
    '2:3' => [
        'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.ration.2_3',
        'value' => 2 / 3
    ],
    '3:4' => [
        'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.ration.3_4',
        'value' => 3 / 4
    ],
    '4:3' => [
        'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.ration.4_3',
        'value' => 4 / 3
    ],
    '3:2' => [
        'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.ration.3_2',
        'value' => 3 / 2
    ],
    '16:9' => [
        'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.ration.16_9',
        'value' => 16 / 9
    ],
];

The second step is the variant configuration. It’s possible to enable your custom variant by force to all sys file references, but my knowledge is, that much useful is to have them disabled and to enable them for specific content (see next step). In this example we also attach our new ratios to the default crop variant.

//typo3conf/ext/boilerplate/Configuration/TCA/Overrides/sys_file_reference.php

// Extended default crop variant with our custom ratios
$GLOBALS['TCA']['sys_file_reference']['columns']['crop']['config']['cropVariants']['default'] = [
    'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.default',
    'allowedAspectRatios' => [
        'NaN' => $allowedRatios['NaN'],
        '1:1' => $allowedRatios['1:1'],
        '3:4' => $allowedRatios['3:4'],
        '2:3' => $allowedRatios['2:3'],
        '4:3' => $allowedRatios['4:3'],
        '3:2' => $allowedRatios['3:2'],
        '16:9' => $allowedRatios['16:9'],
    ],
];


// Crop variant for news listing allows only 16:9 ratio, as default is disabled
$GLOBALS['TCA']['sys_file_reference']['columns']['crop']['config']['cropVariants']['newsListing'] = [
    'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.newsListing',
    'disabled' => true,
    'allowedAspectRatios' => [
        '16:9' => $allowedRatios['16:9'],
    ],
];

Integrate crop variants into you file reference

Imagine you would like to have in news listing always image in ratio 16:9. So easy extend the news TCA and add there the crop variant where is set only the ratio 16:9.

//typo3conf/ext/boilerplate/Configuration/TCA/Overrides/tx_news_domain_model_news.php

$GLOBALS['TCA']['tx_news_domain_model_news']['columns']['fal_media']['config']['overrideChildTca']['columns'] = array_merge($GLOBALS['TCA']['tx_news_domain_model_news']['columns']['fal_media']['config']['overrideChildTca']['columns'], [
        'crop' => [
            'config' => [
                'cropVariants' => [
                    'newsListing' => [
                        'disabled' => false
                    ]

                ]
            ]
        ]
]);

In the template you would call like this. You can also specify the dimensions, but it would come always from the cropped image.

<f:alias map="{mediaElement: newsItem.mediaPreviews.0}">
    <f:image image="{mediaElement}" cropVariant="newsListing" width="600" />
</f:alias>

Another example had happened to me very often. The full screen hero is cutting head of a person in a mobile view.

With crop variants it’s easy to fix it and more then it, it’s also fun.


//typo3conf/ext/boilerplate/Configuration/TCA/Overrides/sys_file_reference.php

// large screens
$GLOBALS['TCA']['sys_file_reference']['columns']['crop']['config']['cropVariants']['large'] = [
    'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.large',
    'disabled' => true,
    'allowedAspectRatios' => [
        'NaN' => $allowedRatios['NaN'],
        '1:1' => $allowedRatios['1:1'],
        '3:4' => $allowedRatios['3:4'],
        '2:3' => $allowedRatios['2:3'],
        '4:3' => $allowedRatios['4:3'],
        '3:2' => $allowedRatios['3:2'],
        '16:9' => $allowedRatios['16:9'],
    ],
];

// medium screens
$GLOBALS['TCA']['sys_file_reference']['columns']['crop']['config']['cropVariants']['medium'] = [
    'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.medium',
    'disabled' => true,
    'allowedAspectRatios' => [
        'NaN' => $allowedRatios['NaN'],
        '1:1' => $allowedRatios['1:1'],
        '3:4' => $allowedRatios['3:4'],
        '2:3' => $allowedRatios['2:3'],
        '4:3' => $allowedRatios['4:3'],
        '3:2' => $allowedRatios['3:2'],
        '16:9' => $allowedRatios['16:9'],
    ],
];

// small screens
$GLOBALS['TCA']['sys_file_reference']['columns']['crop']['config']['cropVariants']['small'] = [
    'title' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:imageManipulation.small',
    'disabled' => true,
    'allowedAspectRatios' => [
        'NaN' => $allowedRatios['NaN'],
        '1:1' => $allowedRatios['1:1'],
        '3:4' => $allowedRatios['3:4'],
        '2:3' => $allowedRatios['2:3'],
        '4:3' => $allowedRatios['4:3'],
        '3:2' => $allowedRatios['3:2'],
        '16:9' => $allowedRatios['16:9'],
    ],
];
//typo3conf/ext/boilerplate/Configuration/TCA/tx_boilerplate_domain_model_hero.php

// TCA column
    'image' => [
            'exclude' => true,
            'label' => 'LLL:EXT:boilerplate/Resources/Private/Language/locallang_be.xlf:tx_boilerplate_domain_model_hero.image',
            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
                'image',
                [
                    'overrideChildTca' => [
                        'types' => [
                            \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
                                'showitem' => '
                                    --palette--;;imageoverlayPalette,
                                    --palette--;;filePalette',
                            ],
                        ],
                        'columns' => [
                            'crop' => [
                                'config' => [
                                    'cropVariants' => [
                                        'default' => [
                                            'disabled' => true
                                        ],
                                        'large' => [
                                            'disabled' => false
                                        ],
                                        'medium' => [
                                            'disabled' => false
                                        ],
                                        'small' => [
                                            'disabled' => false
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ],
                    'maxitems' => 1,
                ],
                $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
            ),

        ],

And as an output we can use picture tag.

<picture>
  <source media="(min-width:1280px)" srcset="{f:uri.image(image: image, cropVariant: 'large', width: '1920')}">
  <source media="(min-width:769px)" srcset="{f:uri.image(image: image, cropVariant: 'medium', width: '1280')}">
  <f:image image="{image}" cropVariant="small" width="769" />
</picture>