MFC高效修改图片像素RGB值,通过像素RGB值生成图片,lifegame图形演示

前言

做一个lifegame的演示程序,lifegame是一个很有名的游戏,现在需要对其结果(二维bool数组)进行图形化演示。如果细胞存活(二维数组中的某一值为1),则对应黑色像素点,否则对应白色像素点。
例如,开局全部像素随机取黑或白,在经历过40次迭代后,其效果如下:
在这里插入图片描述
根据细胞的存活状态对图片的每一像素赋值是一个相当耗时的行为,本文将介绍MFC下的,基于openmp和CImage的解决思路。

openmp

vs2010中使用openmp的例子见Openmp。这篇博文中介绍了openmp的良好性能。
openmp的一个使用前提是对一段共享内存进行并行操作。在本文的例子中,首先需要新建一张图片,接着获取图片所在内存的指针,对其进行修改,最后进行图片的保存。

CImage新建图片并获取图片数据指针

CImage是一个图片处理类,新建一个对象后,可以通过其Create函数新建一张指定大小的图片。通过其Save保存这张图片。CImage本身是有修改图片相应位置像素值的函数SetPixelRGB,如果不考虑并行操作可以直接调用SetPixelRGB对每一个像素进行操作。但是不同线程同时调用image_t.SetPixelRGB会出问题,具体原因未知。
这里通过将CImage对象转换为BITMAP对象,获取图片数据区域的指针,直接对内存进行操作,可以进行并行加速。这里需要注意的是内存区的像素位置和图片中的有所不同,new_grid二维数组的下标对应到图片中为:图片左上角对应(0,0),右下角对应(imax-1,jmax-1)。这里imax和jmax是图片的大小。而内存中有所不同,见代码。

	// 新建一个CImage对象
	CImage image_t;
	// 支持alpha通道
	image_t.Create(imax, jmax, 32, 1);
	// 将CImage对象转换为HBITMAP句柄
	HBITMAP hmp = image_t;
	// 从HBITMAP句柄中获取BITMAP结构体
	BITMAP bmp;
	GetObject(hmp, sizeof(BITMAP), (LPSTR)&bmp);
	// 获取图片存储区域指针
	UINT32* pdata = (UINT32*) bmp.bmBits;
	{
#pragma omp parallel for
	// 并行加速图片生成以及存活细胞数统计
	for(int i = 0; i < imax; i++)
	{
		for (int j = 0; j < jmax; j++)
		{
			if(new_grid[i][jmax-j-1])
			{
				// 黑色
				*(pdata + i + j*imax) = 0;
				//image_t.SetPixelRGB(i, j, 0, 0, 0);
				totalLivingCeils++;
			}
			else
			{
				// 白色
				*(pdata + i + j*imax) = 0xffffff;
				//image_t.SetPixelRGB(i, j, 255, 255, 255);
			}
		}
	}
	}
	
	// 将片保存到磁盘
	CString filename;
	filename.Format(_T("res_%d.jpg"), 0);
	image_t.Save(filename);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fourier_1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值