直入正题
一般的,除了精灵图和掩码图这种间接输出人物之外,还可以通过下面的方法来直接输出人物:
void putpicture(int dstx, int dsty, IMAGE *img, COLORREF color)
{
DWORD *imgp = GetImageBuffer(img);
DWORD *bgimgp = GetImageBuffer();
int w, bw, h, i, j;
w = img->getwidth();
bw = getwidth();
h = img->getheight();
color += 0xff000000;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j)
if (imgp[i*w + j] != color)
bgimgp[(i + dsty)*bw + j + dstx] = imgp[i*w + j];
}
基于这个方法,我们通过一条RGB用的alpha计算公式:
R( C)=alpha*R(B)+(1-alpha)R(A)
G( C)=alphaG(B)+(1-alpha)G(A)
B( C)=alphaB(B)+(1-alpha)*B(A)
可以新造出这么一个函数
void putpicture(int dstx, int dsty, IMAGE *img, COLORREF color, int alpha) {//0~255 255表示不透明
DWORD *imgp = GetImageBuffer(img);
DWORD *bgimgp = GetImageBuffer();
int w, bw, h, i, j;
w = img->getwidth();
bw = getwidth();
h = img->getheight();
color += 0xff000000;
if (alpha < 0)alpha = 0;
else if(alpha>255)alpha=255;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j)
if (imgp[i*w + j] != color)
bgimgp[(i + dsty)*bw + j + dstx] = RGB(
((int)(alpha/255.0* GetRValue(imgp[i*w + j]) + (1 - alpha / 255.0)* GetRValue(bgimgp[(i + dsty)*bw + j + dstx]))),
((int)(alpha / 255.0* GetGValue(imgp[i*w + j]) + (1 - alpha / 255.0)* GetGValue(bgimgp[(i + dsty)*bw + j + dstx]))),
((int)(alpha / 255.0* GetBValue(imgp[i*w + j]) + (1 - alpha / 255.0)* GetBValue(bgimgp[(i + dsty)*bw + j + dstx])))
);
}
用这两个函数,我们可以写出一个示例程序来看看实际对比效果。
人物原图:
背景色纯色RGB(85,85,85)
然后放效果gif图:
示例代码如下:
#include <graphics.h>
void putpicture(int dstx, int dsty, IMAGE *img, COLORREF color)
{
DWORD *imgp = GetImageBuffer(img);
DWORD *bgimgp = GetImageBuffer();
int w, bw, h, i, j;
w = img->getwidth();
bw = getwidth();
h = img->getheight();
color += 0xff000000;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j)
if (imgp[i*w + j] != color)
bgimgp[(i + dsty)*bw + j + dstx] = imgp[i*w + j];
}
void putpicture(int dstx, int dsty, IMAGE *img, COLORREF color, int alpha) {//0~255 255表示不透明
DWORD *imgp = GetImageBuffer(img);
DWORD *bgimgp = GetImageBuffer();
int w, bw, h, i, j;
w = img->getwidth();
bw = getwidth();
h = img->getheight();
color += 0xff000000;
if (alpha < 0)alpha = 0;
else if(alpha>255)alpha=255;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j)
if (imgp[i*w + j] != color)
bgimgp[(i + dsty)*bw + j + dstx] = RGB(
((int)(alpha/255.0* GetRValue(imgp[i*w + j]) + (1 - alpha / 255.0)* GetRValue(bgimgp[(i + dsty)*bw + j + dstx]))),
((int)(alpha / 255.0* GetGValue(imgp[i*w + j]) + (1 - alpha / 255.0)* GetGValue(bgimgp[(i + dsty)*bw + j + dstx]))),
((int)(alpha / 255.0* GetBValue(imgp[i*w + j]) + (1 - alpha / 255.0)* GetBValue(bgimgp[(i + dsty)*bw + j + dstx])))
);
}
int main() {
IMAGE img,bgimg;
int alpha = 0;//用来演示各个alpha数值下的输出情况
loadimage(&img, "C:\\people.png");//这是人物图,纯色背景是RGB(85,85,85)
loadimage(&bgimg, "C:\\a.jpg");//这是程序演示的背景图
initgraph(500, 300);
BeginBatchDraw();
while (1) {
while (MouseHit()) {
if (GetMouseMsg().uMsg == WM_LBUTTONDOWN) {
EndBatchDraw();
closegraph();
return 0;
}
}
putimage(0, 0, &bgimg);//输出程序演示的背景图
putpicture(180, 130, &img, RGB(85, 85, 85));//在右边输出去除纯色背景后的人物图
putpicture(0, 130, &img, RGB(85, 85, 85), alpha);//在左边输出更进一步的人物透明程度图
FlushBatchDraw();
alpha+=3;//数值增加
if (alpha >= 256)//数值归零,完成一次演示
alpha = 0;
Sleep(15);
}
}