3

I have a color 0xADADAD, it was originally white, now it's grey, because it's been alpha blended with 30%(0.3 alpha) black + the unknown original value. In this case I know from lots of trial and error that the original color was 0xF8F8F8

Problem is I have over 20 other colors that need to be fixed like this, but I have no accurate way of finding the original colors. Is there a formula I can do to figure this out? Is it even possible?

  • Given they're both in hex, if a linear transformation were applied, the number at position 1, 3, and 5 (if it's based at 1) would be shifted down by 5 while the ones at 2, 4, and 6 are shifted up by 5. If any other transformation occurred, it's impossible to tell from one example – Zach Saucier Oct 4 '16 at 1:57
  • Is position 1 0xA, therefore I should subtract the value at position 5 (also 0xA) from it, or the actual number 5? Are we shifting bits? Sorry, these terms confuse me. – AlienX Oct 4 '16 at 3:18
  • @AlienX: "0x" is a prefix that indicates you are dealing with base-16 values (aka HEX) it is also common to use "x" or "#" as a prefix. An RGB hex color is a triplet of (3) 2-character values. So "first position" in your example is Red Value=AD (not 0xA). Occasionally you will see someone use a shorthand for values such as "FFF" this is really "x0F0F0F" – Yorik Oct 4 '16 at 16:54
  • Did my post really sound like I don't know what hex is? This still changes nothing, if pos 1, 2, 3 are my hex values what the heck is pos 4, 5, and 6? – AlienX Oct 4 '16 at 22:53
7

Yeah its possible i made a quick change to the code in this post and came up with following very sloppy python 2.X code:

from Tkinter import *
import struct


def ablend(a, fg, bg):
    return ((1-a)*fg[0]+a*bg[0],
            (1-a)*fg[1]+a*bg[1],
            (1-a)*fg[2]+a*bg[2])

def aunblend(a, result, bg):
    return ((result[0]-a*bg[0])/(1-a),
            (result[1]-a*bg[1])/(1-a),
            (result[2]-a*bg[2])/(1-a))


class findUnblendedColor(object):

    def __init__(self, root):
        self.fg=(0xAD, 0xAD, 0xAD)
        self.bg=(255,255,255)
        self.alpha = 0.3

        l = Label(root, text="alpha:")
        l.grid(row=0, column=0)
        label = '0.3'
        self.a = Text(root, height=1,
                       relief=FLAT,
                       width=20,)
        self.a.insert(1.0, label)
        self.a.grid(row=0, column=1)
        self.a.bind("<Return>", self.update)

        l = Label(root, text="Result:")
        l.grid(row=1, column=0)
        label = '#%02x%02x%02x' % self.fg
        self.e = Text(root, height=1,
                       relief=FLAT,
                       width=20,
                       background=label)
        self.e.insert(1.0, label)
        self.e.grid(row=1, column=1)
        self.e.bind("<Return>", self.update)

        l = Label(root, text="BG:")
        l.grid(row=2, column=0)

        label = '#%02x%02x%02x' % self.bg
        self.b = Text(root, height=1,
                       relief=FLAT,
                       width=20,
                       background=label)
        self.b.insert(1.0, label)
        self.b.grid(row=2, column=1)
        self.b.bind("<Return>", self.update)


        l = Label(root, text="FG:")
        l.grid(row=3, column=0)

        col = aunblend(self.alpha, self.fg, self.bg)
        label = '#%02x%02x%02x' % col
        self.f = Text(root, height=1,
                       relief=FLAT,
                       width=20,
                       background=label)
        self.f.insert(1.0, label)
        self.f.configure(state='disabled')
        self.f.grid(row=3, column=1)


        l = Label(root, text="verify:")
        l.grid(row=4, column=0)

        col = ablend(self.alpha, col, self.bg)
        label = '#%02x%02x%02x' % col
        self.g = Text(root, height=1,
                       relief=FLAT,
                       width=20,
                       background=label)
        self.g.insert(1.0, label)
        self.g.configure(state='disabled')
        self.g.grid(row=4, column=1)



    def update(self, event):
        data = self.e.get(1.0,END)
        self.e.delete(1.0, END)
        self.e.insert(END, data[:-1])

        data2 = self.b.get(1.0,END)
        self.b.delete(1.0, END)
        self.b.insert(END, data2[:-1])

        try:
            self.alpha = float(self.a.get(1.0,END)) 

            self.fg = struct.unpack('BBB',data[1:-1].decode('hex'))
            self.e.configure(background=data[:-1])

            self.bg = struct.unpack('BBB',data2[1:-1].decode('hex'))
            self.b.configure(background=data2[:-1])

            col = aunblend(self.alpha, self.fg, self.bg)
            self.f.configure(state='normal')
            self.g.configure(state='normal')

            if all(i <= 256 and i >= 0 for i in col):
                label = '#%02x%02x%02x' % col
                self.f.configure(background=label)

                col = ablend(self.alpha, col, self.bg)
                label2 = '#%02x%02x%02x' % col
                self.g.configure(background=label2)
            else:
                label = "out of range"
                label2 = "out of range"
            self.f.delete(1.0, END)
            self.f.insert(END, label)
            self.g.delete(1.0, END)
            self.g.insert(END, label2)

            self.f.configure(state='disabled')
            self.g.configure(state='disabled')
        except Exception as ex:
            print "error "+repr(type(ex))
            pass

        return 'break'

root = Tk()
root.title("unblend")
findUnblendedColor(root)

root.mainloop()

And you get a window that allows you to type alpha, resulting color and background.

enter image description here

Image 1: Dialog of program

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.