---------------------------------------------------------------- A Bit About Anti-Aliasing and Alpha-Blending
One of the trickiest parts of masking images on top of images is the rough edges, or pixelation, of the meeting places of these images when they are not straight edges. The solution to these rough edges is to blend the edges in a technique called anti-aliasing. In this demo, anti-aliasing is done using an alpha-blending technique, where the transparency of the foreground bitmap pixel determines the strength of color at any particular position on the display.
The formula for blending source and background pixels is:
where the alpha value range is 0 (transparent) to 255 (opaque). Therefore, any part of the button's bitmap that has an alpha value of 0 will not be seen, and areas with values greater than zero will be blended with the background at varying strengths up to 255 where the button's bitmap will be fully opaque.
// alphaBlend routine static inline unsigned int alphaBlend(const unsigned int bg, const unsigned int src) { unsigned int a = src >> 24; // sourceColor alpha
// If source pixel is transparent, just return the background if (0 == a) return bg;
// alpha-blend the src and bg colors unsigned int rb = (((src & 0x00ff00ff) * a) + ((bg & 0x00ff00ff) * (0xff - a))) & 0xff00ff00; unsigned int g = (((src & 0x0000ff00) * a) + ((bg & 0x0000ff00) * (0xff - a))) & 0x00ff0000;
for Row := 0 to Bitmap.Height-1 do begin Col := Bitmap.Width; p := Bitmap.ScanLine[Row];
if Row = 0 then alpha := 100; if Row = 1 then alpha := 80;//50; if Row = 2 then alpha := 60;//155; if Row = 3 then alpha := 45;//200; if Row = 4 then alpha := 30;//255; if Row = 5 then alpha := 20;//255; if Row = 6 then alpha := 10;//255; if Row = 7 then alpha := 5;//255;
if Row = 0 then gray := 1; if Row = 1 then gray := 50; if Row = 2 then gray := 155; if Row = 3 then gray := 200; if Row = 4 then gray := 255;
gray := 0;
while (Col > 0) do begin //p.rgbRed := 110; //p.rgbGreen := 110; //p.rgbBlue := 110;
一般的做法都是用背景色和原色计算出来,除了我忘记的那种方式外。其实还可以用 AlphaBlend 的 windows api 函数来直接画透明色。不过要事先再计算 r,g,b 的值,公式是 r,g,b 分别乘 a / 255 ,即要用 alpha 值来减弱它们本来的值先。 不知道为什么 AlphaBlend 不直接做这一步,感觉很没必要啊。不过 windows 的 api 设计有时候就是很反人类的。
实例如下。delphi 代码,纯 c 的话啰嗦一下点。 ---------------------------------------------------------------- procedure TForm1.Button1Click(Sender: TObject); var Bitmap:TBitmap;
for Row := 0 to Bitmap.Height-1 do begin Col := Bitmap.Width; p := Bitmap.ScanLine[Row];
if Row = 0 then alpha := 100; if Row = 1 then alpha := 80;//50; if Row = 2 then alpha := 60;//155; if Row = 3 then alpha := 45;//200; if Row = 4 then alpha := 30;//255; if Row = 5 then alpha := 20;//255; if Row = 6 then alpha := 10;//255; if Row = 7 then alpha := 5;//255;
if Row = 0 then gray := 1; if Row = 1 then gray := 50; if Row = 2 then gray := 155; if Row = 3 then gray := 200; if Row = 4 then gray := 255;
gray := 0;
while (Col > 0) do begin //p.rgbRed := 110; //p.rgbGreen := 110; //p.rgbBlue := 110;