DEV Community

Dominic Myers
Dominic Myers

Posted on • Originally published at drmsite.blogspot.com on

rgba2rgb

I had a lovely little challenge a couple of days ago which, in conjunction with my invite to the First Alpha Testing of Empire of Code, got me excited. It led me to generate the following chunk of code:

const rgba2rgb = rgba => "#" + rgba.match(/.{1,2}/g)
  .map((c, i, a) => (i !== a.length -1)
    ? parseInt(c, 16)
    : parseInt(c, 16) / 255)
  .map((c, i, a) => (i !== a.length -1)
    ? ~~((1 - a[3]) * 255 + a[3] * c)
    : null)
  .reverse()
  .slice(1)
  .reverse()
  .map(c => c.toString(16))
  .join("");
Enter fullscreen mode Exit fullscreen mode

We needed to convert an RGBA colour to RGB, with the assumption that the original colour was atop a white background. The maths and colour theory are a little confusing, and I went through any number of iterations. The result made me feel a bit smug though as it is teeny - I'm guessing it could be improved though.

Have at it!

EDIT

So I clocked that the above wasn't quite as brilliant as I thought so I've updated it after simplifying it:

const rgba2rgb = function(rgba){
  const coloursAsBase16 = rgba.match(/.{1,2}/g); 
  console.log("coloursAsBase16", coloursAsBase16);
  const coloursAsBase10 = coloursAsBase16.map(function(c, i, a){
    if(i !== a.length - 1) {
      return parseInt(c, 16) // Value between 1 - 255
    } else {
      return parseInt(c, 16) / 255 // Value between 0 - 1}
    }); 
  console.log("coloursAsBase10", coloursAsBase10);
  const coloursWithAlpha = coloursAsBase10.reduce(function(t, c, i, a) {
    if(i !== a.length - 1) {
      return t.concat([parseInt(((1 - a[3]) * 255 + a[3] * c), 10)]);
    } else {
      return t;
    }
  }, []) 
  console.log("coloursWithAlpha", coloursWithAlpha);
  const coloursChangedToBase16 = coloursWithAlpha.map(function(c){
    return c.toString(16)
  }); 
  console.log("coloursChangedToBase16", coloursChangedToBase16);
  return "#" + coloursChangedToBase16.join("");
}
Enter fullscreen mode Exit fullscreen mode

Which led to this one-liner:

const rgba2rgb = rgba => "#" + rgba.match(/.{1,2}/g)
  .map((c, i, a) => (i !== a.length - 1)
    ? parseInt(c, 16)
    : parseInt(c, 16) / 255)
  .reduce((t, c, i, a) => (i !== a.length - 1)
    ? t.concat([parseInt(((1 - a[3]) * 255 + a[3] * c), 10)])
    : t, [])
  .map(c => c.toString(16))
  .join("");
Enter fullscreen mode Exit fullscreen mode

The AI era means career reinvention. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay