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