1 // --------------------------------------------------------------------------- 2 3 // 定义ARGB像素结构 4 typedef union
5 {
6 ARGB Color;
7 struct 8 {
9 BYTE Blue;
10 BYTE Green;
11 BYTE Red;
12 BYTE Alpha;
13 };
14 }ARGBQuad, *PARGBQuad;
15 16 typedef
struct 17 {
18 INT width;
19 INT height;
20 PARGBQuad dstScan0;
21 PARGBQuad srcScan0;
22 INT dstOffset;
23 INT srcOffset;
24 }ImageCpyData, *PImageCpyData;
25 26 typedef VOID (*MixerProc)(PImageCpyData, INT);
27 28 #define PixelAlphaFlag 0x10000
29 // --------------------------------------------------------------------------- 30 // source alpha = false, dest alpha = false, alpha < 255 31 static VOID Mixer0(PImageCpyData cpyData, INT alpha)
32 {
33 PARGBQuad pd = cpyData->dstScan0;
34 PARGBQuad ps = cpyData->srcScan0;
35 for (INT y =
0; y < cpyData->height; y ++, pd += cpyData->dstOffset, ps += cpyData->srcOffset)
36 {
37 for (INT x =
0; x < cpyData->width; x ++, pd ++, ps ++)
38 {
39 pd->Blue += (((ps->Blue - pd->Blue) * alpha +
127) /
255);
40 pd->Green += (((ps->Green - pd->Green) * alpha +
127) /
255);
41 pd->Red += (((ps->Red - pd->Red) * alpha +
127) /
255);
42 }
43 }
44 }
45 // --------------------------------------------------------------------------- 46 // source alpha = false, dest alpha = false, alpha = 255 47 // source alpha = false, dest alpha = true, alpha = 255 48 static VOID Mixer1(PImageCpyData cpyData, INT alpha)
49 {
50 ARGB *pd = (ARGB*)cpyData->dstScan0;
51 ARGB *ps = (ARGB*)cpyData->srcScan0;
52 for (INT y =
0; y < cpyData->height; y ++, pd += cpyData->dstOffset, ps += cpyData->srcOffset)
53 {
54 for (INT x =
0; x < cpyData->width; x ++, *pd ++ = *ps ++);
55 }
56 }
57 // --------------------------------------------------------------------------- 58 // source alpha = false, dest alpha = true, alpha < 255 59 static VOID Mixer2(PImageCpyData cpyData, INT alpha)
60 {
61 PARGBQuad pd = cpyData->dstScan0;
62 PARGBQuad ps = cpyData->srcScan0;
63 for (INT y =
0; y < cpyData->height; y ++, pd += cpyData->dstOffset, ps += cpyData->srcOffset)
64 {
65 for (INT x =
0; x < cpyData->width; x ++, pd ++, ps ++)
66 {
67 pd->Blue = (pd->Blue * pd->Alpha +
127) /
255;
68 pd->Green = (pd->Green * pd->Alpha +
127) /
255;
69 pd->Red = (pd->Red * pd->Alpha +
127) /
255;
70 71 pd->Blue += (((ps->Blue - pd->Blue) * alpha +
127) /
255);
72 pd->Green += (((ps->Green - pd->Green) * alpha +
127) /
255);
73 pd->Red += (((ps->Red - pd->Red) * alpha +
127) /
255);
74 pd->Alpha += (alpha - (pd->Alpha * alpha +
127) /
255);
75 76 pd->Blue = pd->Blue *
255 / pd->Alpha;
77 pd->Green = pd->Green *
255 / pd->Alpha;
78 pd->Red = pd->Red *
255 / pd->Alpha;
79 }
80 }
81 }
82 // --------------------------------------------------------------------------- 83 // source alpha = true, dest alpha = false, alpha < 255 84 static VOID Mixer4(PImageCpyData cpyData, INT alpha)
85 {
86 PARGBQuad pd = cpyData->dstScan0;
87 PARGBQuad ps = cpyData->srcScan0;
88 for (INT y =
0; y < cpyData->height; y ++, pd += cpyData->dstOffset, ps += cpyData->srcOffset)
89 {
90 for (INT x =
0; x < cpyData->width; x ++, pd ++, ps ++)
91 {
92 INT alpha0 = (alpha * ps->Alpha +
127) /
255;
93 pd->Blue += (((ps->Blue - pd->Blue) * alpha0 +
127) /
255);
94 pd->Green += (((ps->Green - pd->Green) * alpha0 +
127) /
255);
95 pd->Red += (((ps->Red - pd->Red) * alpha0 +
127) /
255);
96 }
97 }
98 }
99 // --------------------------------------------------------------------------- 100 // source alpha = true, dest alpha = false, alpha = 255 101 static VOID Mixer5(PImageCpyData cpyData, INT alpha)
102 {
103 PARGBQuad pd = cpyData->dstScan0;
104 PARGBQuad ps = cpyData->srcScan0;
105 for (INT y =
0; y < cpyData->height; y ++, pd += cpyData->dstOffset, ps += cpyData->srcOffset)
106 {
107 for (INT x =
0; x < cpyData->width; x ++, pd ++, ps ++)
108 {
109 pd->Blue += (((ps->Blue - pd->Blue) * ps->Alpha +
127) /
255);
110 pd->Green += (((ps->Green - pd->Green) * ps->Alpha +
127) /
255);
111 pd->Red += (((ps->Red - pd->Red) * ps->Alpha +
127) /
255);
112 }
113 }
114 }
115 // --------------------------------------------------------------------------- 116 // source alpha = true, dest alpha = true, alpha < 255 117 static VOID Mixer6(PImageCpyData cpyData, INT alpha)
118 {
119 PARGBQuad pd = cpyData->dstScan0;
120 PARGBQuad ps = cpyData->srcScan0;
121 for (INT y =
0; y < cpyData->height; y ++, pd += cpyData->dstOffset, ps += cpyData->srcOffset)
122 {
123 for (INT x =
0; x < cpyData->width; x ++, pd ++, ps ++)
124 {
125 INT alpha0 = (alpha * ps->Alpha +
127) /
255;
126 if (alpha0)
127 {
128 pd->Blue = (pd->Blue * pd->Alpha +
127) /
255;
129 pd->Green = (pd->Green * pd->Alpha +
127) /
255;
130 pd->Red = (pd->Red * pd->Alpha +
127) /
255;
131 132 pd->Blue += (((ps->Blue - pd->Blue) * alpha0 +
127) /
255);
133 pd->Green += (((ps->Green - pd->Green) * alpha0 +
127) /
255);
134 pd->Red += (((ps->Red - pd->Red) * alpha0 +
127) /
255);
135 pd->Alpha += (alpha0 - (pd->Alpha * alpha0 +
127) /
255);
136 137 pd->Blue = pd->Blue *
255 / pd->Alpha;
138 pd->Green = pd->Green *
255 / pd->Alpha;
139 pd->Red = pd->Red *
255 / pd->Alpha;
140 }
141 }
142 }
143 }
144 // --------------------------------------------------------------------------- 145 // source alpha = true, dest alpha = true, alpha = 255 146 static VOID Mixer7(PImageCpyData cpyData, INT alpha)
147 {
148 PARGBQuad pd = cpyData->dstScan0;
149 PARGBQuad ps = cpyData->srcScan0;
150 for (INT y =
0; y < cpyData->height; y ++, pd += cpyData->dstOffset, ps += cpyData->srcOffset)
151 {
152 for (INT x =
0; x < cpyData->width; x ++, pd ++, ps ++)
153 {
154 if (ps->Alpha)
155 {
156 pd->Blue = (pd->Blue * pd->Alpha +
127) /
255;
157 pd->Green = (pd->Green * pd->Alpha +
127) /
255;
158 pd->Red = (pd->Red * pd->Alpha +
127) /
255;
159 160 pd->Blue += (((ps->Blue - pd->Blue) * ps->Alpha +
127) /
255);
161 pd->Green += (((ps->Green - pd->Green) * ps->Alpha +
127) /
255);
162 pd->Red += (((ps->Red - pd->Red) * ps->Alpha +
127) /
255);
163 pd->Alpha += (ps->Alpha - (pd->Alpha * ps->Alpha +
127) /
255);
164 165 pd->Blue = pd->Blue *
255 / pd->Alpha;
166 pd->Green = pd->Green *
255 / pd->Alpha;
167 pd->Red = pd->Red *
255 / pd->Alpha;
168 }
169 }
170 }
171 }
172 // --------------------------------------------------------------------------- 173 174 VOID ImageMixer(BitmapData *dest, CONST BitmapData *source, INT alpha)
175 {
176 if (alpha <=
0)
return;
177 if (alpha >
255) alpha =
255;
178 179 ImageCpyData data;
180 data.width = (INT)(dest->Width < source->Width? dest->Width : source->Width);
181 data.height = (INT)(dest->Height < source->Height? dest->Height : source->Height);
182 data.dstOffset = (dest->Stride >>
2) - data.width;
183 data.srcOffset = (source->Stride >>
2) - data.width;
184 data.dstScan0 = (PARGBQuad)dest->Scan0;
185 data.srcScan0 = (PARGBQuad)source->Scan0;
186 187 MixerProc proc[] = {Mixer0, Mixer1, Mixer2, Mixer1, Mixer4, Mixer5, Mixer6, Mixer7};
188 INT index = (alpha /
255) | ((dest->Reserved >>
16) <<
1) | ((source->Reserved >>
16) <<
2);
189 proc[index](&data, alpha);
190 }
191 // ---------------------------------------------------------------------------