BestAns

路漫漫其修远兮,吾将上下而求索

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 中的颜色分量,详见帮助。

[作业]

  1. 实现提高/降低图像亮度的程序。
  2. 自己搜索“灰度算法”,实现彩色图像转换为灰度图像。

评论 (3) -

  • 作业二
    #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);

添加评论