How to change the background of an image with transparent pixels? - language-agnostic

The exact background color is known.
Imagine an anti-aliased font on a green background. Now we want to change the background color of the image to red.
So.. How do I extract the "non-background" portion of the color from the pixel and add it (or "blend") on top of another bg color afterwards?
We also know the font color, so we know which pixels are fully opaque.

Every pixel in the image is either the background color, the font color, or some blend of the two. So you could specify the whole image with the background RGB values, the font RGB values, and an array of values between 0 and 1, where, say, 0 means the pixel is the background color, 1 means the pixel is the font color. A value like 0.1 means that the pixel is mostly background color with a little font color, etc.
An expression like:
blend_value = ((pixel.R - bg.R) / (font.R - bg.R)
+ (pixel.G - bg.G) / (font.G - bg.G)
+ (pixel.B - bg.B) / (font.B - bg.B)) / 3
will give you these values for any pixel in the image. To construct the new RGB values using a new background color, you use this value to blend the font color with the new background color.
new_pixel.R = blend_value * font.R + (1 - blend_value) * new_bg.R
new_pixel.G = blend_value * font.G + (1 - blend_value) * new_bg.G
new_pixel.B = blend_value * font.B + (1 - blend_value) * new_bg.B

Related

Why there are so many color values for HTML like (RGB, HEX, HSL, RGBA, HSLA)? [duplicate]

This question already has answers here:
CSS - hsl or rgb(a) colors
(4 answers)
Closed 4 years ago.
I am a beginner at HTML and CSS. Why are there are so many color values if each of them can be used for a particular color?
It's very simple, all of them use different properties, so you have the power to choose whatever is convenient to you.
RGB = Red, Green and Blue amount from 0 to 255;
HEX = A shorter version of the RGBs amount, you can see how it works here: How does hexadecimal color work?;
HSL = Hue (0 to 360), Saturation and Lightness (both 0 to 100), example: https://www.w3schools.com/colors/colors_hsl.asp (I don't like to quote w3schools but you'll get the point there as well) - basically the first it's the color, second how strong it is, third how light or dark it is;
RGBA = Same of RGB but it'll include and extra value for Alpha, which is the transparency;
Same = Same of HSL but with the Alpha channel mentioned on RGBA as well.

Libgdx change TextButton bg alpha

I have this textbuttons where the user can change the colors, now I want the user to be able to change the alpha too.
When I change the alpha of the font textbutton it only affect the font alpha wich is great. button.getStyle ().fontColor = newColorWithLowAlpha
But when I change the alpha of the button it affects the font alpha too.button.setColor(newColorWithLowAlpha)
Is there a way to change the button alpha without changing the alpha of the text? Thanks

Instead of using a hex code for a color, make it transparent [AS3]

So lets say I have some code in as3, and it requires a given color (Current one is 0x701100 for example) but instead of giving it a hex color code, I want it to be transparent, aka no color, aka see through, you get what I mean.
This is basically the line of code that determines what color it is: super(0x701100, 0x8D1500); and well the 0x8D1500 represents some other things color, but all I want is the 0x701100 to be transparent/not show.
The color 0x701100 is already "transparent" in that it has no value for an alpha channel. It's the same as 0x00701100. A value such as 0xff701100 would represent a fully opaque color, and 0x80701100 would be about 50% transparent. Obviously, the problem is that your super() method does not support rendering transparency from the hex color.

How to change color of pixels of an SKSpriteNode that go over a specific color?

I'm not sure if my title question was clear but what I would like to do is take an SKSpriteNode (or maybe an SKShapeNode) and make it so that whenever it moves over a specific region of the background that has a specific color, it changes the color of ONLY the pixels that are on top to another specified color.
So for example, if I do:
let blackBox = SKSpriteNode(texture: nil, color: UIColor.blackColor(), size: CGSizeMake(100, 100))
blackBox.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
blackBox.zPosition = 5
self.addChild(blackBox)
let redBox = SKSpriteNode(texture: nil, color: UIColor.redColor(), size: CGSizeMake(100, 100))
redBox.position = CGPointMake(CGRectGetMidX(self.frame) + 50, CGRectGetMidY(self.frame) + 50)
redBox.zPosition = 4
self.addChild(redBox)
As you can see the blackBox is on top of the redBox since it has a higher zPosition but it's not completely covering it since the position of the redBox is slightly to the northeast. So in this case the blackBox would be full and the redBox would be covered on its bottom left quadrant.
What I would like to do is make ONLY the portion of the blackBox that is on top of any UIColor.redColor() pixels (ie the top right quadrant of the blackBox) change to another color...say blue for example? How could I program the blackBox node to constantly update the color of its pixels depending on what the color is behind it?
Thanks in advance! :)

Blending with HTML background in WebGL

I am drawing flat colors and textures into WebGL canvas. My colors and textures have varying alpha values and I want them to be blended correctly. I want to have transparent background (they should be blended with HTML content, which is under canvas).
In WebGL, I use
gl.clearColor(0, 0, 0, 0);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.BLEND);
It works correctly, when HTML background is black. But when I set a JPG pattern as a background of , I draw black triangle (alpha=1) and white triangle (alpha=0.5), I can see the background pattern in place where triangles intersect each other. Is this correct behavior?
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) means that the resulting alpha is
A_final = A_s * A_s + (1 - A_s) * A_d
In your example, after the black triangle (with alpha=1) is drawn, a drawn pixel in the framebuffer will have an alpha of
1 * 1 + (1 - 1) * 0 == 1 + 0 == 1
So it will be fully opaque. Next, after the white triangle (with alpha=.5) is drawn, a pixel in the intersection of the two triangles will have an alpha of
.5 * .5 + (1 - .5) * 1 == .25 + .5 == .75
That means the final color will be treated as partially transparent, and, when it is composited with the page, the page background will show through.
This is a somewhat uncommon problem in regular OpenGL, since content is usually composited against an empty background. It does come up when you draw to an FBO and have to composite the results with other content in your context, though. There are a few ways to deal with this.
One way is to have your alpha blend with gl.ONE, gl.ONE_MINUS_SRC_ALPHA so you get
A_final = A_s + (1 - A_s) * A_d
which is what you usually want with alpha blending. However, you want your colors to still blend with gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA. You can use gl.blendFuncSeparate instead of gl.blendFunc to set your color blending and alpha blending functions separately. In this case, you would call
gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
Another option is to take advantage of colors with premultiplied alpha (which WebGL actually already assumes you are using, for instance, when sampling a color from a texture). If you draw the second triangle with the alpha already multiplied through the color (so a half transparent white triangle would have gl_FragColor set to vec4(.5, .5, .5, .5)), then you can use the blend mode
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
and it will act as you want for both color and alpha.
The second option is what you'll commonly see in WebGL examples, since (as mentioned), WebGL already assumes your colors are premultiplied (so vec4(1., 1., 1., .5) is out of gamut, the rendering output is undefined, and the driver/GPU can output any crazy color it wants). It's far more common to see gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) in regular OpenGL examples, which leads to some confusion.