Computing "average" of two colors
This is only marginally programming related - has much more to do w/ colors and their representation.
I am working on a very low level app. I have an array of bytes in memory. Those are characters. They were rendered with anti-aliasing: they have values from 0 to 255, 0 being fully transparent and 255 totally opaque (alpha, if you wish).
I am having trouble conceiving an algorithm for the rendering of this font. I'm doing the following for each pixel:
// intensity is the weight I talked about: 0 to 255
intensity = glyphs[text[i]][x + GLYPH_WIDTH*y];
if (intensity == 255)
continue; // Don't draw it, fully transparent
else if (intensity == 0)
setPixel(x + xi, y + yi, color, base); // Fully opaque, can draw original color
else { // Here's the tricky part
// Get the pixel in the destination for averaging purposes
pixel = getPixel(x + xi, y + yi, base);
// transfer is an int for calculations
transfer = (int) ((float开发者_运维知识库)((float) (255.0 - (float) intensity/255.0) * (float) color.red + (float) pixel.red)/2); // This is my attempt at averaging
newPixel.red = (Byte) transfer;
transfer = (int) ((float)((float) (255.0 - (float) intensity/255.0) * (float) color.green + (float) pixel.green)/2);
newPixel.green = (Byte) transfer;
// transfer = (int) ((float) ((float) 255.0 - (float) intensity)/255.0 * (((float) color.blue) + (float) pixel.blue)/2);
transfer = (int) ((float)((float) (255.0 - (float) intensity/255.0) * (float) color.blue + (float) pixel.blue)/2);
newPixel.blue = (Byte) transfer;
// Set the newpixel in the desired mem. position
setPixel(x+xi, y+yi, newPixel, base);
}
The results, as you can see, are less than desirable. That is a very zoomed in image, at 1:1 scale it looks like the text has a green "aura".
Any idea for how to properly compute this would be greatly appreciated.
Thanks for your time!
You need to blend the background and foreground colours. A-la:
pixelColour = newColour * intensity + backgroundColour * (1 - intensity)
By the way, this is a really slow way of rendering and blending fonts. You should instead render all the characters of the font to an off-screen surface with all the properties you need, and then use that as a texture to render to other surfaces when you need text.
Edit:
This doesn't look right:
(255.0 - (float) intensity/255.0)
It should instead be:
(255.0 - (float) intensity)/255.0
I believe that "aura" is caused by anti aliasing. The technique averages pixels with their neighbors.
I realize you don't seem to be using OpenGL but this chapter might help explain some of the theory. Wish I had a better answer, but hopefully this points you in the right direction. My first attempt would be to disable Antialiasing since it seems to do more harm than good. There is probably a better solution than that though.
It may be too much complicated to doing alpha blending pixel by pixel because current pixel value modifies next pixel value.
I would redesign the algorithm with the thinking of box wise blending.
With many getPixel calling for a single glyph, you can't produce proper target image.
精彩评论