VC绘图/游戏简易教程--14:通过位运算实现颜色的分离与处理
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
本节课要求熟练掌握位运算,详见:
http://hi.baidu.com/bestans/blog/item/fb75b439404876e614cecb9f.html (已失效)
[颜色基础]
在 EasyX 库中,颜色是一个 int 类型的数据,转换为 16 进制后的颜色格式是 0xbbggrr,其中,bb/gg/rr 分别表示两位十六进制的蓝/绿/红颜色值,每种颜色的范围是 0x0~0xff,转换为十进制就是 0~255。
举几个颜色标示的例子:
- 颜色 直接表示 RGB 宏标示
- 纯绿色 0x00ff00 RGB(0, 255, 0)
- 青色 0xffff00 RGB(0, 255, 255) 注:青=蓝+绿
- 中灰色 0x7f7f7f RGB(127, 127, 127)
- 黄色 0x00ffff RGB(255, 255, 0) 注:黄=红+绿
例如设置绘图颜色为黄色,可以多种方法,例如:
- setcolor(YELLOW);
- setcolor( RGB(255, 255, 0) );
- setcolor(0x00ffff);
[获取颜色]
getpixel 是用来获取屏幕颜色的函数,其返回值为 int 类型的颜色。例如:
int c = getpixel(100, 100); // 该语句将返回坐标 (100, 100) 位置的颜色。
[颜色分离与处理]
有时候我们需要修改颜色某一位的值,这时,可以通过位运算来实现。比如,我们想把某一个点的颜色的红色部分去掉,可以这么做:
int c = getpixel(100, 100);
c &= 0xffff00;
putpixel(100, 100);
我们来看一个完整的程序,这个程序,将图片左半部中的红色“去掉”了,就像是显示器“缺色”的效果:
#include <graphics.h>
#include <conio.h>
int main()
{
initgraph(640, 480);
// 读取图片
loadimage(NULL, _T("D:\\test.jpg"));
int c;
for(int x = 0; x < 320; x++)
for(int y = 0; y < 480; y++)
{
c = getpixel(x, y);
c = (0xff0000 - (c & 0xff0000)) | (0x00ff00 - (c & 0x00ff00)) | (0x0000ff - (c & 0x0000ff));
putpixel(x, y, c);
}
_getch();
closegraph();
return 0;
}
继续实践,找到这行:
c &= 0xffff00;
我们修改为:
c = (0xff0000 - (c & 0xff0000)) | (0x00ff00 - (c & 0x00ff00)) | (0x0000ff - (c & 0x0000ff));
在执行看看效果,就成了照片的底片效果。
注:通过宏 GetRValue / GetGValue / GetBValue 可以直接获取 COLORREF 中的颜色分量,详见帮助。
[作业]
- 实现提高/降低图像亮度的程序。
- 自己搜索“灰度算法”,实现彩色图像转换为灰度图像。
COLORREF RGBtoGRAY(
COLORREF rgb
);
#include <graphics.h>
#include <conio.h>
int main()
{
initgraph(640, 480);
// 读取图片
loadimage(NULL, _T("D:\\3-Desktop\\test.jpg"));
int c;
for (int x = 0; x < 640; x++)
for (int y = 0; y < 480; y++)
{
c = getpixel(x, y);
int R = GetRValue(c);
int G = GetGValue(c);
int B = GetBValue(c);
//方法一
int GRay = R * 0.299 + G * 0.587 + B * 0.114;
//方法二
int GRay2 = (R * 30 + G * 59 + B * 11 + 50) / 100;
//方法三
int GRay3 = (R * 19595 + G * 38469 + B * 7472) >> 16;
//方法四
int GRay4 = (R + G + B) / 3;
c = RGB(GRay, GRay, GRay);
putpixel(x, y, c);
}
_getch();
closegraph();
return 0;
}
int nColor = getpixel(220, 200);
//转RGB
//方法一
int red = nColor & 255;
int green = nColor >> 8 & 255;
int blue= nColor >> 16 & 255;
//方法二
int red = GetRValue(nColor);
int green = GetGValue(nColor);
int blue = GetBValue(nColor);
//RGB转
int nColor2 = RGB(50, 20, 80);