个人填充图形算法之四方格式扫描[含透明化背景以输出人物]

简介

使用库:easyx
语言:C++
描述:功能:当当前点是要替换的颜色时候,查询周围四格是否有HIDE_COLOR这个目标色,
如果有则将当前点替换成HIDE_COLOR,没有则继续下一个

方法:循环往复地扫描,对于复杂程度高的图形需要反复进行扫描,一般图形,一次扫描即可完成
随着扫描次数增多,再内凹曲折的不规则图形也终究会被替换干净

先放一下成果图:
成果图

使用该算法前应该具有的前置代码:

#define HIDE_COLOR 0xFF555555//设置目标颜色
struct color_group{//先建立一个用来存储颜色的结构体
	BYTE r;//这三个是要换成HIDE_COLOR的颜色的RGB
	BYTE g;
	BYTE b;
	BYTE rl;//这六项是要被替换的颜色所允许的误差范围,即用来判断是否是相似色
	BYTE gl;
	BYTE bl;
	BYTE rr;
	BYTE gr;
	BYTE br;
	BYTE rs;//这三项是扫描到的点本身的RGB三色
	BYTE gs;
	BYTE bs;
};

在具备了上述前置代码后,则开始使用以下代码开始计算:

/计算准备
	IMAGE img;
	int w, h;
	DWORD *src;
	COLORREF color = 0xFB8BFF;//要被替换的颜色 这里是粉色
	int color_go = 20;//偏差20范围的颜色视作为相似
	color_group p;//生成实例
	p.r = GetRValue(color);//获得要被替换的颜色的RGB三色
	p.g = GetGValue(color);
	p.b = GetBValue(color);
	p.rl = p.r < color_go ? 0 : p.r - color_go ;//COLOR_GO是误差值,这里用来获取误差区间
	p.gl = p.g < color_go ? 0 : p.g - color_go ;
	p.bl = p.b < color_go ? 0 : p.b - color_go ;
	p.rr = p.r > 255 - color_go ? 255 : 255 - color_go ;
	p.gr = p.g > 255 - color_go  ? 255 : 255 - color_go ;
	p.br = p.b > 255 - color_go ? 255 : 255 - color_go ;
	loadimage(&img, TEXT("a.jpg"));//装载目标图像:TEXT("路径+文件名")这种写法是为了自适应当前编码
	w = img.getwidth(), h = img.getheight();//获取图像宽高
	src = GetImageBuffer(&img);//得到图像缓冲区
	/算法实现
	for (san = num; san>0; --san) {//扫描次数由san来管理,这里是扫描四次
	for (j = 0; j < h; ++j) {
		for (i = 0; i < w; ++i) {//上方横向扫描线向下扫描开始
			p.rs = GetRValue(src[i + j * w]);
			p.gs = GetGValue(src[i + j * w]);
			p.bs = GetBValue(src[i + j * w]);
			if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
				if (i - 1 >= 0 && src[i - 1 + j * w] == HIDE_COLOR || i + 1 < w && src[i + 1 + j * w] == HIDE_COLOR ||
					j - 1 >= 0 && src[i + (j - 1)*w] == HIDE_COLOR || j + 1 < h && src[i + (j + 1)*w] == HIDE_COLOR)
					src[i + j * w] = HIDE_COLOR;
			}
		}
	}
	for (j = h - 2; j >= 0; --j) {
		for (i = 0; i < w; ++i) {//下方横向扫描线向上扫描开始
			p.rs = GetRValue(src[i + j * w]);
			p.gs = GetGValue(src[i + j * w]);
			p.bs = GetBValue(src[i + j * w]);
			if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
				if (i - 1 >= 0 && src[i - 1 + j * w] == HIDE_COLOR || i + 1 < w && src[i + 1 + j * w] == HIDE_COLOR ||
					j - 1 >= 0 && src[i + (j - 1)*w] == HIDE_COLOR || j + 1 < h && src[i + (j + 1)*w] == HIDE_COLOR)
					src[i + j * w] = HIDE_COLOR;
			}
		}
	}
	for (i = 1; i < w; ++i) {
		for (j = 0; j < h; ++j) {//左方竖向扫描线向右扫描开始
			p.rs = GetRValue(src[i + j * w]);
			p.gs = GetGValue(src[i + j * w]);
			p.bs = GetBValue(src[i + j * w]);
			if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
				if (i - 1 >= 0 && src[i - 1 + j * w] == HIDE_COLOR || i + 1 < w && src[i + 1 + j * w] == HIDE_COLOR ||
					j - 1 >= 0 && src[i + (j - 1)*w] == HIDE_COLOR || j + 1 < h && src[i + (j + 1)*w] == HIDE_COLOR)
					src[i + j * w] = HIDE_COLOR;
			}
		}
	}
	for (i = w - 1; i >= 0; --i) {
		for (j = 0; j < h; ++j) {//右方竖向扫描线向左扫描开始
			p.rs = GetRValue(src[i + j * w]);
			p.gs = GetGValue(src[i + j * w]);
			p.bs = GetBValue(src[i + j * w]);
			if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
				if (i - 1 >= 0 && src[i - 1 + j * w] == HIDE_COLOR || i + 1 < w && src[i + 1 + j * w] == HIDE_COLOR ||
					j - 1 >= 0 && src[i + (j - 1)*w] == HIDE_COLOR || j + 1 < h && src[i + (j + 1)*w] == HIDE_COLOR)
					src[i + j * w] = HIDE_COLOR;
			}
		}
	}
}

在放出完整实例前这里要特别提醒一下,由于该循环的特殊(即需要图中先存在HIDE_COLOR),所以要先进行一下边框的扫描来转换边框这部分像素颜色为HIDE_COLOR

完整实例:

#include <graphics.h>
#include <conio.h>
#define HIDE_COLOR 0xFF555555//设置目标颜色
struct color_group {//先建立一个用来存储颜色的类
	BYTE r;//这三个是要换成HIDE_COLOR的颜色的RGB
	BYTE g;
	BYTE b;
	BYTE rl;//这六项是要被替换的颜色所允许的误差范围
	BYTE gl;
	BYTE bl;
	BYTE rr;
	BYTE gr;
	BYTE br;
	BYTE rs;//这三项是扫描到的点本身的RGB三色
	BYTE gs;
	BYTE bs;
};
//函数实现:
void quit_color(int num, int &w,int &h,COLORREF& color, DWORD *(&src), color_group &p) {
	static int i, j, san;
	//开始对边框进行扫描
	for (i = 0; i < w; ++i) {//建立上方横向扫描线
		p.rs = GetRValue(src[i]);
		p.gs = GetGValue(src[i]);
		p.bs = GetBValue(src[i]);
		if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br || src[i] == HIDE_COLOR) {
			src[i] = HIDE_COLOR;
		}
	}
	for (i = 0; i < w; ++i) {//建立下方横向扫描线
		p.rs = GetRValue(src[i + (h - 1)*w]);
		p.gs = GetGValue(src[i + (h - 1)*w]);
		p.bs = GetBValue(src[i + (h - 1)*w]);
		if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br || src[i + (h - 1)*w] == HIDE_COLOR) {
			src[i + (h - 1)*w] = HIDE_COLOR;
		}
	}
	for (j = 0; j < h; ++j) {//建立左方竖向扫描线
		p.rs = GetRValue(src[j*w]);
		p.gs = GetGValue(src[j*w]);
		p.bs = GetBValue(src[j*w]);
		if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br || src[j*w] == HIDE_COLOR) {
			src[j*w] = HIDE_COLOR;
		}
	}
	for (j = 0; j < h; ++j) {//建立右方竖向扫描线
		p.rs = GetRValue(src[w - 1 + j * w]);
		p.gs = GetGValue(src[w - 1 + j * w]);
		p.bs = GetBValue(src[w - 1 + j * w]);
		if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br || src[w - 1 + j * w] == HIDE_COLOR) {
			src[w - 1 + j * w] = HIDE_COLOR;
		}
	}
	for (san = num; san>0; --san) {//扫描次数由san来管理,这里是扫描四次
		for (j = 0; j < h; ++j) {
			for (i = 0; i < w; ++i) {//上方横向扫描线向下扫描开始
				p.rs = GetRValue(src[i + j * w]);
				p.gs = GetGValue(src[i + j * w]);
				p.bs = GetBValue(src[i + j * w]);
				if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
					if (i - 1 >= 0 && src[i - 1 + j * w] == HIDE_COLOR || i + 1 < w && src[i + 1 + j * w] == HIDE_COLOR ||
						j - 1 >= 0 && src[i + (j - 1)*w] == HIDE_COLOR || j + 1 < h && src[i + (j + 1)*w] == HIDE_COLOR)
						src[i + j * w] = HIDE_COLOR;
				}
			}
		}
		for (j = h - 2; j >= 0; --j) {
			for (i = 0; i < w; ++i) {//下方横向扫描线向上扫描开始
				p.rs = GetRValue(src[i + j * w]);
				p.gs = GetGValue(src[i + j * w]);
				p.bs = GetBValue(src[i + j * w]);
				if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
					if (i - 1 >= 0 && src[i - 1 + j * w] == HIDE_COLOR || i + 1 < w && src[i + 1 + j * w] == HIDE_COLOR ||
						j - 1 >= 0 && src[i + (j - 1)*w] == HIDE_COLOR || j + 1 < h && src[i + (j + 1)*w] == HIDE_COLOR)
						src[i + j * w] = HIDE_COLOR;
				}
			}
		}
		for (i = 1; i < w; ++i) {
			for (j = 0; j < h; ++j) {//左方竖向扫描线向右扫描开始
				p.rs = GetRValue(src[i + j * w]);
				p.gs = GetGValue(src[i + j * w]);
				p.bs = GetBValue(src[i + j * w]);
				if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
					if (i - 1 >= 0 && src[i - 1 + j * w] == HIDE_COLOR || i + 1 < w && src[i + 1 + j * w] == HIDE_COLOR ||
						j - 1 >= 0 && src[i + (j - 1)*w] == HIDE_COLOR || j + 1 < h && src[i + (j + 1)*w] == HIDE_COLOR)
						src[i + j * w] = HIDE_COLOR;
				}
			}
		}
		for (i = w - 1; i >= 0; --i) {
			for (j = 0; j < h; ++j) {//右方竖向扫描线向左扫描开始
				p.rs = GetRValue(src[i + j * w]);
				p.gs = GetGValue(src[i + j * w]);
				p.bs = GetBValue(src[i + j * w]);
				if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
					if (i - 1 >= 0 && src[i - 1 + j * w] == HIDE_COLOR || i + 1 < w && src[i + 1 + j * w] == HIDE_COLOR ||
						j - 1 >= 0 && src[i + (j - 1)*w] == HIDE_COLOR || j + 1 < h && src[i + (j + 1)*w] == HIDE_COLOR)
						src[i + j * w] = HIDE_COLOR;
				}
			}
		}
	}
	return;
}
int main()
{
	IMAGE img;
	int  w, h;
	DWORD *src;
	COLORREF color = 0xFB8BFF;//要被替换的颜色 这里是粉色
	int color_go = 20;//偏差20范围的颜色视作为相似
	color_group p;//生成实例
	p.r = GetRValue(color);//获得要被替换的颜色的RGB三色
	p.g = GetGValue(color);
	p.b = GetBValue(color);
	p.rl = p.r < color_go ? 0 : p.r - color_go;//COLOR_GO是误差值,这里用来获取误差区间
	p.gl = p.g < color_go ? 0 : p.g - color_go;
	p.bl = p.b < color_go ? 0 : p.b - color_go;
	p.rr = p.r > 255 - color_go ? 255 : 255 - color_go;
	p.gr = p.g > 255 - color_go ? 255 : 255 - color_go;
	p.br = p.b > 255 - color_go ? 255 : 255 - color_go;
	loadimage(&img, TEXT("a.png"));//装载目标图像:TEXT("路径+文件名")这种写法是为了自适应当前编码
	w = img.getwidth(), h = img.getheight();//获取图像宽高
	src = GetImageBuffer(&img);//得到图像缓冲区
	initgraph(w*2, h);//准备演示
	HWND hWnd = GetHWnd();//获得窗口句柄
	int ExdStyle = (int)GetWindowLong(hWnd, GWL_EXSTYLE);
	SetWindowLong(hWnd, GWL_EXSTYLE, ExdStyle | WS_EX_LAYERED);
	SetLayeredWindowAttributes(hWnd, HIDE_COLOR, 255, LWA_COLORKEY);//指定为颜色HIDE_COLOR透明
	setbkcolor(HIDE_COLOR);//设置设备背景色
	cleardevice();//清洗背景
	putimage(0, 0, &img);//输出原图像
	quit_color(5,w,h,color,src,p);//开始除去除该颜色 5是扫描五次的意思
	putimage(img.getwidth(), 0, &img);//输出对比图像
	_getch();//如果这里出错就换成getch();
	closegraph();
	return 0;
}

这次就沿用上次使用的测试用透明图来表达
效果图:
左边原图,右边替换后的透明图
对比图
可以看见,我不仅放大了要扫描的图(800*800),而且仅用了五次扫描后,就使得如此极端内凹的图形也被扫的像这样干净的,而且就目前的运算速度来说是立刻扫描完毕的。

现在,让我们提高一下扫描次数,变成7次
对比图

剩余的一点也被弄的干干净净了,速度依旧还是立刻扫描完毕。

思考:好!这样的效果像之前的递归函数一般,却不会那样费栈,相当干净!但是,如果我这里有这样的图,我想把它稍微里面一定的也给扫掉,变成透明,可以吗?
问题图

答:没有问题!直接就在这篇博客中回答你的问题,因为这个问题仅需修改一点点上面的代码就能实现!

新增加的代码用/**/来解释
完整代码如下:

#include <graphics.h>
#include <conio.h>
#define HIDE_COLOR 0xFF555555//设置目标颜色
struct color_group {//先建立一个用来存储颜色的类
	BYTE r;//这三个是要换成HIDE_COLOR的颜色的RGB
	BYTE g;
	BYTE b;
	BYTE rl;//这六项是要被替换的颜色所允许的误差范围
	BYTE gl;
	BYTE bl;
	BYTE rr;
	BYTE gr;
	BYTE br;
	BYTE rs;//这三项是扫描到的点本身的RGB三色
	BYTE gs;
	BYTE bs;
};
//函数实现:		/*在这里加了一个新参数jump_point,用来扩大检测的范围*/
void quit_color(int num, int jump_point,int &w,int &h,COLORREF& color, DWORD *(&src), color_group &p) {
	static int i, j, san;
	static int var;/*新增的工具人变量*/
	//开始对边框进行扫描
	for (i = 0; i < w; ++i) {//建立上方横向扫描线
		p.rs = GetRValue(src[i]);
		p.gs = GetGValue(src[i]);
		p.bs = GetBValue(src[i]);
		if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br || src[i] == HIDE_COLOR) {
			src[i] = HIDE_COLOR;
		}
	}
	for (i = 0; i < w; ++i) {//建立下方横向扫描线
		p.rs = GetRValue(src[i + (h - 1)*w]);
		p.gs = GetGValue(src[i + (h - 1)*w]);
		p.bs = GetBValue(src[i + (h - 1)*w]);
		if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br || src[i + (h - 1)*w] == HIDE_COLOR) {
			src[i + (h - 1)*w] = HIDE_COLOR;
		}
	}
	for (j = 0; j < h; ++j) {//建立左方竖向扫描线
		p.rs = GetRValue(src[j*w]);
		p.gs = GetGValue(src[j*w]);
		p.bs = GetBValue(src[j*w]);
		if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br || src[j*w] == HIDE_COLOR) {
			src[j*w] = HIDE_COLOR;
		}
	}
	for (j = 0; j < h; ++j) {//建立右方竖向扫描线
		p.rs = GetRValue(src[w - 1 + j * w]);
		p.gs = GetGValue(src[w - 1 + j * w]);
		p.bs = GetBValue(src[w - 1 + j * w]);
		if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br || src[w - 1 + j * w] == HIDE_COLOR) {
			src[w - 1 + j * w] = HIDE_COLOR;
		}
	}
	for (san = num; san>0; --san) {//扫描次数由san来管理,这里是扫描四次
		for (j = 0; j < h; ++j) {
			for (i = 0; i < w; ++i) {//上方横向扫描线向下扫描开始
				p.rs = GetRValue(src[i + j * w]);
				p.gs = GetGValue(src[i + j * w]);
				p.bs = GetBValue(src[i + j * w]);
				for (var = 1; var < jump_point;++var) {
					if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
						if (i - var >= 0 && src[i - var + j * w] == HIDE_COLOR || i + var < w && src[i + var + j * w] == HIDE_COLOR ||/*这里面将1换成了var*/
							j - var >= 0 && src[i + (j - var)*w] == HIDE_COLOR || j + var < h && src[i + (j + var)*w] == HIDE_COLOR)
							src[i + j * w] = HIDE_COLOR;
					}
				}
			}
		}
		for (j = h - 2; j >= 0; --j) {
			for (i = 0; i < w; ++i) {//下方横向扫描线向上扫描开始
				p.rs = GetRValue(src[i + j * w]);
				p.gs = GetGValue(src[i + j * w]);
				p.bs = GetBValue(src[i + j * w]);
				for (var = 1; var < jump_point; ++var) {
					if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
						if (i - var >= 0 && src[i - var + j * w] == HIDE_COLOR || i + var < w && src[i + var + j * w] == HIDE_COLOR ||/*这里面将1换成了var*/
							j - var >= 0 && src[i + (j - var)*w] == HIDE_COLOR || j + var < h && src[i + (j + var)*w] == HIDE_COLOR)
							src[i + j * w] = HIDE_COLOR;
					}
				}
			}
		}
		for (i = 1; i < w; ++i) {
			for (j = 0; j < h; ++j) {//左方竖向扫描线向右扫描开始
				p.rs = GetRValue(src[i + j * w]);
				p.gs = GetGValue(src[i + j * w]);
				p.bs = GetBValue(src[i + j * w]);
				for (var = 1; var < jump_point; ++var) {
					if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
						if (i - var >= 0 && src[i - var + j * w] == HIDE_COLOR || i + var < w && src[i + var + j * w] == HIDE_COLOR ||/*这里面将1换成了var*/
							j - var >= 0 && src[i + (j - var)*w] == HIDE_COLOR || j + var < h && src[i + (j + var)*w] == HIDE_COLOR)
							src[i + j * w] = HIDE_COLOR;
					}
				}
			}
		}
		for (i = w - 1; i >= 0; --i) {
			for (j = 0; j < h; ++j) {//右方竖向扫描线向左扫描开始
				p.rs = GetRValue(src[i + j * w]);
				p.gs = GetGValue(src[i + j * w]);
				p.bs = GetBValue(src[i + j * w]);
				for (var = 1; var < jump_point; ++var) {
					if (p.rs >= p.rl && p.rs <= p.rr && p.gs >= p.gl && p.gs <= p.gr && p.bs >= p.bl && p.bs <= p.br) {
						if (i - var >= 0 && src[i - var + j * w] == HIDE_COLOR || i + var < w && src[i + var + j * w] == HIDE_COLOR ||/*这里面将1换成了var*/
							j - var >= 0 && src[i + (j - var)*w] == HIDE_COLOR || j + var < h && src[i + (j + var)*w] == HIDE_COLOR)
							src[i + j * w] = HIDE_COLOR;
					}
				}
			}
		}
	}
	return;
}
int main()
{
	IMAGE img;
	int  w, h;
	DWORD *src;
	COLORREF color = 0xffffff;//要被替换的颜色 这里是粉色
	int color_go = 20;//偏差20范围的颜色视作为相似
	color_group p;//生成实例
	p.r = GetRValue(color);//获得要被替换的颜色的RGB三色
	p.g = GetGValue(color);
	p.b = GetBValue(color);
	p.rl = p.r < color_go ? 0 : p.r - color_go;//COLOR_GO是误差值,这里用来获取误差区间
	p.gl = p.g < color_go ? 0 : p.g - color_go;
	p.bl = p.b < color_go ? 0 : p.b - color_go;
	p.rr = p.r > 255 - color_go ? 255 : 255 - color_go;
	p.gr = p.g > 255 - color_go ? 255 : 255 - color_go;
	p.br = p.b > 255 - color_go ? 255 : 255 - color_go;
	loadimage(&img, TEXT("a.png"));//装载目标图像:TEXT("路径+文件名")这种写法是为了自适应当前编码
	w = img.getwidth(), h = img.getheight();//获取图像宽高
	src = GetImageBuffer(&img);//得到图像缓冲区
	initgraph(w*2, h);//准备演示
	HWND hWnd = GetHWnd();//获得窗口句柄
	int ExdStyle = (int)GetWindowLong(hWnd, GWL_EXSTYLE);
	SetWindowLong(hWnd, GWL_EXSTYLE, ExdStyle | WS_EX_LAYERED);
	SetLayeredWindowAttributes(hWnd, HIDE_COLOR, 255, LWA_COLORKEY);//指定为颜色HIDE_COLOR透明
	setbkcolor(HIDE_COLOR);//设置设备背景色
	cleardevice();//清洗背景
	putimage(0, 0, &img);//输出原图像
	quit_color(7,12,w,h,color,src,p);//开始除去除该颜色
	putimage(img.getwidth(), 0, &img);//输出对比图像
	_getch();//如果这里出错就换成getch();
	closegraph();
	return 0;
}

对比图
可以看见,较好的实现了内部的颜色去除,但是还有一处似乎没有清理到?

那是因为这个算法仅仅是十字式检查的,哪个位置恰好不在十字范围内,没能替换掉。这个算法可以升级成像个“米”字的检查方式,这样就能更好地探测到一些人物内部的隐蔽位置。

但这样的做法是存在问题的:

  1. .随着jump_point这个变量的增大,就越容易误杀人物内部的像素
  2. 由于运算量的增加,会导致有一段时间图像处在处理中,无法第一时间显示出除色后的图像

完成这个算法后,我的桌宠的自动纯色背景透明的功能终于也成熟了起来。
你想知道如何实现自动背景透明而不是像这样要手动更改需要被替换的颜色?
其实也挺取巧的,把color的值来源换成src[0]就能做到了!这是一个取巧的方法。

好了,暂且告一段落。

如今初入DSDN,将解决的算法一步步的分享出来,请各位多多包涵,有文章逻辑或排版问题还请指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值