Getting the average color of an image in Sanity CMS

36 replies
Last updated: Dec 3, 2020
I have a question, which can also be a feature request 🙂 I want to get the average color of an image (or maybe 2 or 3 color palettes). Now, these are normally done by requesting a smaller image resolution, perform some kind of pixel color average and then use that value. since its a bit expensive I wonder if this can be set when the user updates / changes an image in sanity. Either by a custom component or automatically. Did anyone ever done something like this on the CMS instead of client-side?
Dec 2, 2020, 9:57 PM
Hey
user A
– take a quick look at the metadata info on the image object, if you resolve reference and add this, you can get plenty of palette info about every image. I managed to use this very reliably on https://joshlilley.com/ to change header colour on image hover and background behind image while they load
Dec 3, 2020, 9:20 AM
With the out of the box image schema? Or you build something custom?
Dec 3, 2020, 9:35 AM
out the box!
Dec 3, 2020, 10:58 AM
have a look at image docs / request an image with metadata
Dec 3, 2020, 10:59 AM
Simon is right, this should be available to you out of the box, at least to some degree depending on what you need 🙂 Have a look at this example of a
sanity.imageAsset
document: https://www.sanity.io/docs/image-type#example-of-a-image-asset-object-with-metadata-location-lqip-palette-and-dimensions-df3f768ce073
The data is inside the
metadata.palette
object.
Dec 3, 2020, 12:31 PM
ah okay. this means that on my sanity studio schema I need to specifically request palette
Dec 3, 2020, 12:36 PM
no
Dec 3, 2020, 12:36 PM
so any images uploaded without that bit won’t have it on the database?
Dec 3, 2020, 12:36 PM
oh…
Dec 3, 2020, 12:36 PM
Cause this is my current GROQ request, and nothing comes on that imageMetadata field besides “type” and “asset”
Dec 3, 2020, 12:37 PM
  "image": image {
    ...,
    "metadata": asset->metadata
  }
This probably isn’t the best way, I don’t know! But I simply request it like this – I think you might have the wrong name for it, unless I’m missing something
Dec 3, 2020, 12:38 PM
I’ll test your suggestion now. but I was reading this article and that gave me the impression I need to specify “options” on my image schema
Dec 3, 2020, 12:39 PM
I guess the docs could define more clearly that these things are extracted by default, as youre right it doesnt say
Dec 3, 2020, 12:41 PM
Indeed, we should probably clarify that these attributes are recorded by default. Thanks for the feedback!
Dec 3, 2020, 12:42 PM
Image assets also contain useful metadata such as Low Quality Image Previews (LQIP), palette information and original image dimension as well as aspect ratio.
It does mention here, but not where you’d look for it
Dec 3, 2020, 12:43 PM
sorry to keep dragging this, but let me share what I have, cause i’m rather confused..
Dec 3, 2020, 12:43 PM
{
            name: 'coverImage',
            title: 'Cover Image',
            type: 'image',
            fieldset: 'settings',
            validation: (Rule) => Rule.required(),
        },
Dec 3, 2020, 12:44 PM
This is my post image schema. just a “normal” image”
Dec 3, 2020, 12:44 PM
and this is how I’m getting it:
Dec 3, 2020, 12:44 PM
*[_type == "post"] | order(title) {
  'key': _id,
  'type': _type,
  title,
  'slug': slug.current,
  'image': coverImage.asset->url,
}
Dec 3, 2020, 12:45 PM
but if I just get
'image': coverImage
the object I get is a reference and it has no palette info
Dec 3, 2020, 12:45 PM
yes htats correct
Dec 3, 2020, 12:47 PM
because images are documents too
Dec 3, 2020, 12:47 PM
so are stored as references
Dec 3, 2020, 12:47 PM
this means you need to resolve them to get information you might want, like the url you are extracting
Dec 3, 2020, 12:47 PM
->
the GROQ you are using here resolves the reference to the asset and extracts the URL
Dec 3, 2020, 12:48 PM
however you need more than one property, so could tryu something like:
'image': coverImage {
  'url': asset->url,
  'metadata': asset->metadata
}
Dec 3, 2020, 12:48 PM
ah I see!
Dec 3, 2020, 12:49 PM
thanks buddy!
Dec 3, 2020, 12:49 PM
I got it
Dec 3, 2020, 12:49 PM
Now my issue will be decoding why the hell there’s so many classifications for the palette 😄 I’ll go through the docs and figure out what is a darkVibrant vs darkMuted and which one should I sample to get the average colors
Dec 3, 2020, 12:50 PM
the best is simply to do a quick overview of options on your frontend – sometimes not all are present in my experience, so you may need to look for more than one
Dec 3, 2020, 12:51 PM
and do a “eye” comparison to what’s closest to the image from all the palette’s and then choose one? sounds good!
Dec 3, 2020, 12:52 PM
(P.S. You could probably rewrite to this if you prefer)
'image': coverImage.asset->{
  url,
  metadata
}
Dec 3, 2020, 12:53 PM
Yeah its way more clean. still a n00b at groq. thanks guys. appreciate it
Dec 3, 2020, 2:07 PM

Sanity– build remarkable experiences at scale

The Sanity Composable Content Cloud is the headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?