Lxndwich Posted July 30, 2023 Share Posted July 30, 2023 I have this image, which I am planning on using as a profile picture, that I had someone make for me on commission some time ago. I accidentally flattened/saved the PSD using the PSD plugin, and the person I paid for the art no longer has the original PSD either. Since I can't undo this, I need to reverse-engineer the color/alpha of the glasses lenses so that I can recreate the glasses separately for an edit I plan on making, but also so I can restore the file to its original layered state. Quote Insert signature here. Link to comment Share on other sites More sharing options...
frio Posted July 30, 2023 Share Posted July 30, 2023 The glasses are most likely pure white for highlights, #3c93f9 the rest. 255 alpha, multiply blend. I just based it on guesswork: since the whites (pure white #ffffff) of the eyes are unchanged under the highlights but become blue elsewhere, using multiply blend with the blue-on-eye-whites color sounded correct, and after testing with a dummy layer it appears to be at least very close. Quote Link to comment Share on other sites More sharing options...
Disk4mat Posted July 31, 2023 Share Posted July 31, 2023 Real long shot. But you might have the original file as a shadow copy. If your Windows is a pro version you can right click the file, select properties and go to the previous versions tab. If you dont have previous versions, you can try Shadow Explorer (link). Its free and a life saver at times. Quote Link to comment Share on other sites More sharing options...
_koh_ Posted July 31, 2023 Share Posted July 31, 2023 If you still keep background layer you can back calculate most of it, but I don't believe this is the case. Quote Link to comment Share on other sites More sharing options...
Solution LWChris Posted August 13, 2023 Solution Share Posted August 13, 2023 (edited) I have been thinking about creating a plugin called "Color Unmixer" to answer exactly these questions of reverse engineering. Sadly, I've not yet gotten around to think of a good custom UI. But luckily, having had those plans means I have a good understanding of how it should work, and I can do for you by hand what the plugin should've done if it existed already. So... here we go! The Maths, the Basics, and You Finding the semi-transparent overlay color boils down to a system of 4 linear equations that you can solve if you have two pixels with distinct known background colors "b1" and "b2" that were overlain by the same unknown semi-transparent foreground color "f". That is, as long as both colors were overlain by the same foreground color at the same opacity, you can mathematically calculate that foreground color and its opacity. Your image has several of these pairs, so it should be possible to work out the color. But first of all, one thing I noticed right away: the outlines are not affected by the glass, i.e. the oval outline of the eyes stays black, no matter if it should be "under" the blue tint or highlight or not under the glasses at all. So my guess is those outlines were on a separate layer ABOVE the glasses. But that's probably something you remembered anyway. For the other bits, there's 4 pairs for both the highlight and the tint on the glasses. I've marked them red, yellow, lime and blue here (the 3rd lime marker is in the top right). Any "pair" consists of one of the base colors (outside of the glasses) and then either the corresponding part on the tinted or highlighted part of the glasses, respectively. Having 4 pairs per unknown overlay color is cool, because we can use two to determine the color and its opacity, and the other two to check if our calculations "add up" (literally) as a sanity check. But first, here's the actual formula what the visible mixed color "m" becomes when a semi-transparent foreground color "f" is overlayed over the background color "b": mc = bc + (fc - bc) * falpha / 255 This formula is applied per channel "c". For example, for the red channel, the formula would be: mred = bred + (fred - bred) * falpha / 255 The keen-eyed can probably also see why we need 2 pixel pairs: since we want to know the semi-transparent foreground color, we have to re-arrange that formula to solve for the f's (more on that later). But we have to make a choice: we can either solve for the red channel value fred, or for the alpha channel value falpha. Any m/b pair will produce three equations, one for each channel, and we can use those to solve for fred, fgreen and fblue respectively. But we then need a fourth equation from a different pair to also give us some formula we can instead re-arrange to solve for falpha. With all that being said, there's two snags we need to pay attention to: Snag 1: If the values for a color channel between background color and resulting mixed color match, that means the foreground color used the same color value (or maybe a really close one with very low opacity) for that channel, but we cannot use that equation any longer to solve for falpha. This makes sense; if you overlay "some amount of redness" with "any transparency of same amount of redness", the resulting mix will still have that same redness value to it, no matter the actual transparency. [Side note: this is also visible from the formula. If mred = bred, that means the calculation must've been "mred = bred + [something that equals 0]". This can either mean that falpha was 0, which is not really interesting, because I think we agree the overlay was probably not 100% transparent, or "fred - bred = 0", which means "fred = bred", and that's what we stated when we said that background and foreground use the same red value, or "(fred - bred) * falpha / 255" is so small it gets rounded to 0.] Snag 2: This one is not as obvious from the formula, but becomes clear once you start crunching numbers. RGB colors are discrete values, that is: integers. The formula works perfect for floating values, where mixed red values like 15.7311248 would be a possibility. Alas, in the actual image the red value is probably either 15 or more likely 16. That's something we need to keep in mind, and it is the reason why many online maths solvers might probably say that the system of equations cannot be solved, because with all that rounding, the results between channels or different pairs etc. just not quite "line up" when calculating forwards and backwards again. But we'll deal with that later. The Highlights But now: to the actual solving! Let's start with the highlight color first, so the pairs are going to be the background colors from outside the glasses plus the respective color from inside the glasses where these have a highlight. For the blue pair, both m and b are #FFFFFF. As per snag 1, we cannot use that to determine the highlight falpha, but at least it's probably safe to assume it was "some transparency of clean #FFFFFF white". We'll use the yellow pair to find that alpha value: The background color for the yellow markers (iris) is b = #56C3F6, the mixed result on the glass is m = #89D5F9. Let's use the red channel, since it exhibits the most intense value change from bred = 56hex to mred = 89hex, which equals bred = 86 to mred = 137 in decimal numbers. Now let's re-arrange our formula to solve for falpha: mc = bc + (fc - bc) * falpha / 255 mc - bc = (fc - bc) * falpha / 255 (mc - bc) / (fc - bc) = falpha / 255 (mc - bc) / (fc - bc) * 255 = falpha There we have it, we can use this formula to get falpha: falpha = (mc - bc) / (fc - bc) * 255 Inserting the values for mred = 137, bred = 86 and fred = 255 (which, remember, we deduced from the "clean white"), we get 76.95266272189..., so basically 77. Hence we predict the highlight color to be "#FFFFFF with a transparency of 77". Let's test our theory by applying the original formula "mc = bc + (fc - bc) * falpha / 255" to the lime pair. Here are the known values for the lime pair (where "m" is the one located in the highlight, not the tint): b = #FBD574 = rgb(251, 213, 116) m = #FCE29E = rgb(252, 226, 158) f = rgba(255, 255, 255, 77) Now we plug the values for b and f into the formula, and see if that correctly predicts m: mred = 251 + (255 - 251) * 77 / 255 = 252.21 mgreen = 213 + (255 - 213) * 77 / 255 = 225.68 mblue = 116 + (255 - 116) * 77 / 255 = 157.97 And sure enough, if we round those values to whole numbers, we get m = rgb(252, 226, 158). Now for the red pair: b = #FCEDDA = rgb(252, 237, 218) m = #FDF2E5 = rgb(253, 242, 229) mred = 252 + (255 - 252) * 77 / 255 = 252.91 mgreen = 237 + (255 - 237) * 77 / 255 = 242.44 mblue = 218 + (255 - 218) * 77 / 255 = 229.17 Again, rounding those values to whole numbers, we correctly get m = rgb(253, 242, 229). Hooray, the highlight color is indeed "#FFFFFF with a transparency of 77", just like we predicted earlier. Yay for Maths! The Blue Tint Now let's do the same thing for the blue tint. This time, it's going to require a little bit more effort, since the tint color isn't obvious already. But worry not, it's the same maths like for falpha, but we're re-arranging the original equation to solve for fc instead of falpha, and then use that formula for red, green, and blue: mc = bc + (fc - bc) * falpha / 255 mc - bc = (fc - bc) * falpha / 255 (mc - bc) * 255 = (fc - bc) * falpha (mc - bc) * 255 / falpha = fc - bc (mc - bc) * 255 / falpha + bc = fc We can use this formula to get fc: fc = (mc - bc) * 255 / falpha + bc Let's use it on the yellow pair. Here are the known values: b = #56C3F6 = rgb(86, 195, 246) m = #3C93F9 = rgb(60, 147, 249) Plugging in those two colors for all three channels, we get three equations which are only dependent on falpha: fred = (60 - 86) * 255 / falpha + 86 fgreen = (147 - 195) * 255 / falpha + 195 fblue = (249 - 246) * 255 / falpha + 246 From the blue pair, we get these known values: b = #FFFFFF = rgb(255, 255, 255) m = #B2BDFF = rgb(178, 189, 255) This gives these equations: fred = (178 - 255) * 255 / falpha + 255 fgreen = (189 - 255) * 255 / falpha + 255 fblue = (255 - 255) * 255 / falpha + 255 Since we know (or rather: require) all equations come from the same f (i.e.: with the same fred, and the same falpha), we can essentially solve for falpha by equating yellow's fred and the blue's fred, and then re-arrange the resulting equation to solve for falpha: fred = (60 - 86) * 255 / falpha + 86 fred = (178 - 255) * 255 / falpha + 255 (60 - 86) * 255 / falpha + 86 = (178 - 255) * 255 / falpha + 255 -26 * 255 / falpha + 86 = -77 * 255 / falpha + 255 -26 * 255 / falpha = -77 * 255 / falpha + 169 51 * 255 / falpha = 169 51 * 255 = 169 * falpha 51 * 255 / 169 = falpha falpha = 76.95266272189349 Hey! That value looks awfully familiar, doesn't it? Yep, we landed on the same result as with the highlight color earlier. In hindsight, it's probably not too surprising that we got the same transparency value of "77" for both parts of the glass. The glasses were probably created on a separate layer using opaque colors and a uniform layer transparency of 77. But now we know for sure (and I could include the steps to calculate falpha for a non-trivial case). Anyway, back to the original "yellow equations". Now that we have confirmed that falpha is indeed 77, we can complete those equations and hopefully get our foreground color. So here goes nothing: fred = (60 - 86) * 255 / 77 + 86 = -0.10 fgreen = (147 - 195) * 255 / 77 + 195 = 36.04 fblue = (249 - 246) * 255 / 77 + 246 = 255.94 Here we have a classic example of snag 2. The "known" values were rounded, so reversing the operation has lead to slight deviations from the original colors. We get negative values such as -0.10, or values like 255.94, which would get rounded to 256 and thereby exceed the possible maximum of 255. But for now, let's reasonably assume f to be rgba(0, 36, 255, 77) and see where that assumption takes us. We can check it using the other two pairs - and that's why having such extra pairs for verification is so nice. Let's test red first. Known colors: b = #FCEDDA = rgb(252, 237, 218) m = #B0B0E5 = rgb(176, 176, 229) Assuming f = rgba(0, 36, 255, 77), the formula suggests: mred = 252 + (0 - 252) * 77 / 255 = 175.91 mgreen = 237 + (36 - 237) * 77 / 255 = 176.31 mblue = 218 + (255 - 218) * 77 / 255 = 229.17 Great news! These values check out for our observed m. Now, for our final test, we check the lime pair. Known colors: b = #FBD574 = rgb(251, 213, 116) m = #B0A09E = rgb(176, 160, 158) And one last time, assuming f = rgba(0, 36, 255, 77), the formula suggests: mred = 251 + (0 - 251) * 77 / 255 = 175.21 mgreen = 213 + (36 - 213) * 77 / 255 = 159.55 mblue = 116 + (255 - 116) * 77 / 255 = 157.97 Spot on! Nice. The Answer And there we have it. From using nothing but the final result and Maths, we can deduce: The glasses were made using a highlight color of #FFFFFF and a tint color of #0024FF, on a layer with "77" transparency. Cheers, Chris Edited August 13, 2023 by LWChris 4 1 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.