Conversation
|
It might be worthwhile looking into calculating this upon upload and stored in the meta vs on the fly in browser. It could be something as simple as: use Intervention\Image\ImageManagerStatic as Image;
$image = Image::make($path)->resize(1, 1, function ($constraint) {
$constraint->aspectRatio();
});
$averageColor = $image->pickColor(0, 0); // [R, G, B, A]
// Normalized to 0-1
$meanR = $averageColor[0] / 255;
$meanG = $averageColor[1] / 255;
$meanB = $averageColor[2] / 255;
$luminance = (0.2126 * $meanR) + (0.7152 * $meanG) + (0.0722 * $meanB);
$isBright = $luminance > 0.5;(not tested AI generated - but looks correct) |
|
The brightness/luminance would indeed be interesting on the frontend as well, now that everything is glass and backdrop filters :) With the additional benefit of front-loading the calculation at the time of upload. |
…r uses the server-provided tone directly, falling back to client-side Canvas detection only for SVGs.
… with a transparent background, so it can skip transparent pixels and only measure the actual content. This works independently of the user's configured image driver -- if the Imagick PHP extension is installed, SVGs get tone detection; if not, they get null gracefully. Raster image detection is unchanged (still uses Intervention Image).
|
OK, I've given it a go! I've updated the PR description to note what's happening.
You could use it like this: {{ if asset:tone == "light" }}
<div class="preview preview-dark">
{{ elseif asset:tone == "dark" }}
<div class="preview preview-light">
{{ /if }}
<img src="{{ asset:url }}" alt="" />
</div>Or with the booleans: {{ if asset:is_light_tone }}
<div class="bg-dark">…</div>
{{ elseif asset:is_dark_tone }}
<div class="bg-light">…</div>
{{ /if }} |
|
This is really nice. Great solution to a tricky situation. |
|
Did you push up the antlers stuff? I don't see anything. |
… button to show transparency
when the Imagick branch finds zero non-transparent pixels (meaning it couldn't meaningfully rasterize the SVG), it now falls through to the XML color-parsing fallback instead of returning null. Same for when Imagick throws an exception.
|
@jasonvarga the Antlers syntax should "just work" because we're referencing saved meta data. Here's some Antlers and the browser rendering it in the background: |
…Vue file when server generation has not taken place yet




Description of the Problem
As discussed in #13927, transparent assets can be primarily light or dark.
Under certain conditions, it can be difficult to discern an image against a checkerboard background—for example, when the logo is white or black.
What this PR Does
by sampling pixels using built-in browser APIs (Canvas 2D + Image). This is computed server-side on upload using Intervention Image (works with both GD and Imagick drivers) and stored in the asset's.meta/*.yamlfile alongside existing metadata likewidth,height, andduration.(Updated since initial PR):
How it works
lightordark) is written to meta astone.tone: null.generateMeta()pipeline.Exposed to developers in Antlers templates
{{ tone }}-- returnslight,dark, or null{{ is_light_tone }}/{{ is_dark_tone }}-- boolean helpersWorks the same way as
focus_cssand other meta-driven asset values.Before
(and you'd have a similar problem if you had a dark logo with a dark checkerboard background)
After
White and black logos are now much easier to discern:
(ignore the aspect ratio issue here, that's an existing issue that I'll fix separately)
How to Reproduce
/cp/assetsand upload a transparent white or black logo