Craft CMS Asked on March 31, 2021
In my product catalog, some product images need to have the css attribute object-fit: cover
while some need the object-fit: contain
:
I’d like to detect the white background, possibly on upload (to ease processing when live). I am currently using Imager for transforms, and I would guess that plugin could have some detection feature, but I can’t seem to find it.
Reading around a little suggests reading all four corners of the image and determine white bg if all four pixels are white — but how can I do this? (and how can I do it on file upload?)
Craft CMS has a powerful event system that lets you attach to events and then perform further actions on the entities involved.
I created a site module based on nystudio107’s template, and inserted the provided code.
Then I created the field hasWhiteBackground
as a lightswitch field, and ran a console command ./craft assets/resave
as documented in the Craft CMS 3 docs, to update the lightswitch for existing assets.
I am using imager
to transform the images and to create srcset
. I use the hasWhiteBackground
to do either a fit
or crop
mode to the resize operation:
{% set image = p.productImage.one()|default(null) %}
{% set transformedImages = craft.imager.transformImage(image, [
{ width: 269 },
{ width: 246 },
{ width: 209 }
], {
ratio: 1/1,
position: image.getFocalPoint()|default("50% 50%"),
mode: image.hasWhiteBackground|default(false) ? 'fit' : 'crop'
})
%}
I then added the class contain
to each image outputted:
class="{{ image.hasWhiteBackground ? 'contain'}}">
The class simply adds the following css to the image:
.contain {
object-fit:contain;
}
Here is what the result looks like:
Interesting problem! I took a stab at this, see if this works for your use case.
It relies on ImageMagick to check for the top left pixel color (0,0) after the image is uploaded (but will also work if you hit resave). (If you want to check the other 3 corners, you'll need more code but this should get you started.)
To use it, you'll need a lightswitch field called hasWhiteBackground
on your asset volume (or change the name in the script).
The light switch gets switched to true if the top right corner of the image is white or transparent.
The "magic" is in the getImagePixelColor
function.
Event::on(
craftelementsAsset::class,
craftelementsAsset::EVENT_BEFORE_SAVE,
function(crafteventsModelEvent $event) {
$asset = $event->sender;
if ($asset->kind == 'image' ) {
if ($event->isNew) {
$assetFilePath = $asset->tempFilePath;
} else {
$volumePath = $asset->getVolume()->settings['path'];
$folderPath = '/' . $asset->getFolder()->path;
$assetFilePath = Craft::getAlias($volumePath) . $folderPath . $asset->filename;
}
$img = new Imagick($assetFilePath);
$pixel = $img->getImagePixelColor(1, 1);
$p = $pixel->getColor();
if (($p['r'] == 255 && $p['g'] == 255 && $p['b'] == 255) || ($p['r'] == 0 && $p['g'] == 0 && $p['b'] == 0 && $p['a'] == 0)) {
$asset->setFieldValue('hasWhiteBackground','1');
}
}
});
Correct answer by RitterKnight on March 31, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP