首先 有三张图片,一张背景图,我这里是两张人物图,现在要把人物图贴在背景里,并且去掉人物图片的背景,好让人物很好的嵌入到背景中,这两张图片的背景要是黑色的
只要思路就是,先要获得人物图的掩码图,就是黑白相间的图片,白色部分是要去掉的背景,黑色部分是要显示的人物,
下面是一个方法,传入IMAGE对象,返回掩码图的IMAGE对象,然后只用先后put到绘图设备中就可以了,
IMAGE qubeijing(IMAGE aa) {
//SetWorkingImage(&aa);// 设置绘图目标为 aa 对象
int width = aa.getwidth();
int height = aa.getheight();//获取长和宽
IMAGE maskbitmap(width, height); //创建一个掩码图
DWORD *pmemflower = GetImageBuffer(&aa);
DWORD *pmemmaskbitmap = GetImageBuffer(&maskbitmap);
COLORREF maskbk = pmemflower[0];//这里0应该是左上角的像素的颜色值
for (int i = 0; i<width * height; i++)
{
if (pmemflower[i] <= 0x010101 && pmemflower[i] >= 0)//0x55555555是深灰色 xAAAAAA 浅灰 0XF5F5F5 烟白 && pmemflower[i] >= 0
{
pmemmaskbitmap[i] = WHITE ;
//白色是背景,我想让背景少一点,大于的颜色越白,进这里的机会越少
}
else
pmemmaskbitmap[i] = BLACK;
}
//for 遍历每个像素值,如果颜色小于灰色 ,掩码图对应像素值为 纯白,否则为纯黑
//得到 黑白相间 的掩码图
return maskbitmap;
}
put到绘图设备中时,先把掩码图put到绘图设备中
putimage(0, 280, &mni, SRCAND);
&mni 是 掩码图的引用,
SRCAND 在 EasyX文档里有说
SRCAND | 绘制出的像素颜色 = 屏幕颜色 AND 图像颜色 |
注:
1. AND / OR / NOT / XOR 为布尔运算。
2. "屏幕颜色"指绘制所经过的屏幕像素点的颜色。
3. "图像颜色"是指通过 IMAGE 对象中的图像的颜色。
4. "当前填充颜色"是指通过 setfillcolor 设置的用于当前填充的颜色。
5. 查看全部的三元光栅操作码请点这里:三元光栅操作码。
//任意颜色 与 白色 做 与 运算 得到任意颜色
//任意颜色 与 黑色 做 与 运算 得到黑色
//任意颜色 与 白色 做 或 运算 得到白色
//任意颜色 与 黑色 做 或 运算 得到任意颜色
putimage(150, 280, &ni, SRCPAINT);
这里的 SRCPAINT 在文档上是这样说的
SRCPAINT | 绘制出的像素颜色 = 屏幕颜色 OR 图像颜色 |
结合上面的说明, 黑色部分与任意颜色做 或 运算 得到任意颜色,这时候putimage 前后的两张图的黑色部分会被另一张图的颜色替换, 就OK了
我的资源文件是
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#ifdef APSTUDIO_INVOKED
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
NI IMAGE "ni.jpg" //下面 引入的三个图片
WO IMAGE "wo.jpg"
gj IMAGE "bj.jpg"
#endif // 中文(简体,中国) resources
#ifndef APSTUDIO_INVOKED
#endif // not APSTUDIO_INVOKED
在看代码
#include "stdafx.h"
#include <graphics.h> // 引用图形库头文件
#include <conio.h>
#include <windows.h>
#include "resource.h"
#include <iostream>
using namespace std;
IMAGE bj;
IMAGE ni;
IMAGE wo;
void init(); //初始化函数
IMAGE qubeijing(IMAGE aa);//去除背景 传入需要去背景的图片,传出去玩背景的图片
void main()
{
init();
//cout << _T("C:\\Users\\Administrator\\Desktop\\nn.jpg");
/*initgraph(640, 480); // 创建绘图窗口,大小为 640x480 像素
loadimage(NULL, _T("IMAGE"), _T("wo"));
system("pause");*/
return ;
}
void init() {
//
initgraph(1200,600); // 创建绘图窗口,大小为 640x480 像素
loadimage(&bj, _T("IMAGE"), _T("gj"), 1200, 600);
putimage(0, 0, &bj);//设置背景
loadimage(&ni, _T("IMAGE"), _T("NI"),150,330); //宽150 高 300
loadimage(&wo, _T("IMAGE"), _T("WO"), 150, 330);
//loadimage(NULL, _T("C:\\Users\\Administrator\\Desktop\\nn.jpg"));
IMAGE mni=qubeijing(ni);
BeginBatchDraw();//一会一块把图像刷新到屏幕
putimage(0, 280, &mni, SRCAND);//and 的关系 ,白色and屏幕原色,出现原色 ,黑色and屏幕原色 ,出现黑色
putimage(0, 280, &ni, SRCPAINT);// or 的 关系
//你绘制玩了
IMAGE mwo = qubeijing(wo);
putimage(150, 280, &mwo, SRCAND); //显示图片 距左 距上
putimage(150, 280, &wo, SRCPAINT);
FlushBatchDraw();
EndBatchDraw();
//circle(200, 200, 100); // 画圆,圆心(200, 200),半径 100
system("pause"); // 按任意键继续
closegraph(); // 关闭绘图窗口
}
IMAGE qubeijing(IMAGE aa) {
//SetWorkingImage(&aa);// 设置绘图目标为 aa 对象
int width = aa.getwidth();
int height = aa.getheight();//获取长和宽
IMAGE maskbitmap(width, height); //创建一个掩码图
DWORD *pmemflower = GetImageBuffer(&aa);
DWORD *pmemmaskbitmap = GetImageBuffer(&maskbitmap);
COLORREF maskbk = pmemflower[0];//这里0应该是左上角的像素的颜色值
for (int i = 0; i<width * height; i++)
{
if (pmemflower[i] <= 0x010101 && pmemflower[i] >= 0)//0x55555555是深灰色 xAAAAAA 浅灰 0XF5F5F5 烟白 && pmemflower[i] >= 0
{
pmemmaskbitmap[i] = WHITE ;
//白色是背景,我想让背景少一点,大于的颜色越白,进这里的机会越少
}
else
pmemmaskbitmap[i] = BLACK;
}
//for 遍历每个像素值,如果颜色小于灰色 ,掩码图对应像素值为 纯白,否则为纯黑
//得到 黑白相间 的掩码图
return maskbitmap;
}
//任意颜色 与 白色 做 与 运算 得到任意颜色
//任意颜色 与 黑色 做 与 运算 得到黑色
//任意颜色 与 白色 做 或 运算 得到白色
//任意颜色 与 黑色 做 或 运算 得到任意颜色
效果
素材是: