开发者社区> 贾志刚> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

在VC++中使用CxImage库读写图像实现像素操作

简介: 最近做了一个项目最后要把算法整成C++的DLL方式给别人调用,朋友给我推荐了用CxImage这个库来读写图像文件,所以我就用了,基于CxImage做了调用算法的Demo程序,已经给别人测试了,现在总结一下CxImage使用中遇到的那些坑。
+关注继续查看
最近做了一个项目最后要把算法整成C++的DLL方式给别人调用,朋友给我推荐了用CxImage这个库来读写图像文件,所以我就用了,基于CxImage做了调用算法的Demo程序,已经给别人测试了,现在总结一下CxImage使用中遇到的那些坑。

坑一:
我是VS2015上面用CxImage这个库的,而且是别人已经编译好的LIB与头文件直接给我了,他还是VC6.0上面搞出来的,所以我一使用这个库遇到第一个问题就是在Link的时候给我报缺少DLL文件mfc42d.dll和msvcrtd.dll这两个DLL文件找不到,我的是VS2015当然没有这个两个东西,还好CSDN博客专家群里面有个哥们很好,传给我了,帮我解决了这个问题。后来我找到CxImage上code project上面的文章,发现它果然是用VC6.0编译的。http://www.codeproject.com/Articles/1300/CxImage

坑二:
然后我就开始使用这个库了,只要加上如下的头文件:
#include "ximage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#pragma comment(lib,"cximaged.lib")

发现我编译怎么也不通过,后来我才发现原因了,我是好久不搞C++了,设置Link的路径不对。可见我已经把我知道的东西全部还给我的大学老师了。解决这个问题就可以使用了,CxImage可以读写几何所有常见格式图像文件,我主要用它来读写JPG和PNG文件,这样就可以省去我很多力气。读JPG文件的代码如下:

AfxMessageBox("从这里打开图像文件...");
CString strFile = _T("");
CFileDialog dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files (*.jpg)|*.jpg|All Files (*.*)|*.*||"), NULL);
if (dlgFile.DoModal())
{
	strFile = dlgFile.GetPathName();
}
AfxMessageBox(strFile);
bool blLoad = this->image.Load(strFile, CXIMAGE_FORMAT_JPG);
if (this->image.IsValid()) {
	AfxMessageBox("文件装载成功...");
	this->Invalidate();
}

坑三:

也是因为我好久不搞C++了,我有个统计直方图的来了个数组定义,然后就直接开始统计直方图了,其实C++中数组一定要初始化,不然它的初始值真的不是0啊,我把它当成Java来搞了,发现统计出来的直方图数据居然有负值,经过这个血泪教育我知道VC++一定要初始化数组,不然结果很吓人。

坑四:
然后我就读像素了,CxImage中读图像像素数据的我找了好久发现只有一个GetBits()官方的API上面说这个可以获得像素数组的指针,指向第0个像素地址,可是API注释上面还有一句英文说这个API非常危险,要小心使用。还好我胆子比较大,不管它就直接用了,发现这个里面有个大坑,就是它的像素指针的第一个是我们倒是第一行,我们要读一幅图像从上到下,从左到右顺序的话,在图像高度的方向就要从height-1读到0,而不是从0读到height-1.最终我实现了利用CxImage读取图像像素数据,实现图像灰度化,同时还画了两条红色的线。

代码如下:

if (this->image.IsValid()) {
	AfxMessageBox("图像灰度化...");

	int maxY = image.GetHeight(), 
	int maxX = image.GetWidth();
	int size = maxX*maxY;
	BYTE* bs = image.GetBits();
	int w=((((24 * image.GetWidth()) + 31) / 32) * 4); // 4字节对齐
	for (int j=0; j<maxY; j++) {
		for (int i=0; i<maxX; i++) {
			BYTE *b = bs+(image.GetHeight()-1-j)*w +i*3;
			int blue =*(b);
			int green =*(b+1);
			int red =*(b+2);
			int grayVal=(int)red*0.3+(int)green*0.59+(int)blue*0.11;
			CString csStr;
			csStr.Format("%d", grayVal);
			if(i >10 && i<100) {
				if(j == 50 || j== 100) {
					*b = 0; //blue
					*(b+1) = 0; // green
					*(b+2) = 255; // red
				}
				else {
					*b = grayVal;
					*(b+1) = grayVal;
					*(b+2) = grayVal;
				}
			}
			else {
				*b = grayVal;
				*(b+1) = grayVal;
				*(b+2) = grayVal;
			}
		}
	}
	this->Invalidate();
}
显示图像在View中,VC++中显示图像一定要放到OnDraw方法中

不然就得自己做各种窗口事件响应处理实现重绘制。代码如下:

// TODO: 在此处为本机数据添加绘制代码
if (this->image.IsValid()) {
	int h = this->image.GetHeight(),	// + 256
	int w = this->image.GetWidth();

	CRect rc;
	GetClientRect(&rc);
	rc.right = rc.left +w;
	rc.bottom = rc.top + h;
	this->image.Draw(pDC->GetSafeHdc(), rc);
}
这样就搞定了CxImage读写图像文件的全部内容,需要说明一下

我这里的图像都是RGB三通道的,在读取像素之前,最好检查一

下它是几通道的图像。载入一张图片:


利用CxImage读取图像实现灰度图像效果:


发现这样我就可以把精力放到图像处理算法本身了,用VC++搞图像

处理的算法也是可以的,没想象中那么恶搞!

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【C++学习】函数对象和Lambda表达式
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 在看《高效编程十八式》中的第一小节的时候介绍了函数对象方法和Lambda表达式,以便完成“如果需要对函数指针进行更加灵活的定制”。
789 0
【C++学习】默认构造函数的常见问题
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.什么是默认构造函数? 一个函数是默认构造函数当且仅当调用它可以不需要传入任何参数。这个函数可以是用户自定义的,也可以是编译器产生的。
710 0
【C++学习】复制构造函数和赋值运算符根本的不同
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 首先要说明的是,若用户没有定义,C++隐式声明一个复制构造函数和一个赋值运算符(完成按数据成员复制的动作)。
606 0
【C++学习】类初始化列表的分析总结
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.在子类构造时完成父类(没有默认构造函数)的初始化参数传入: #include class Foo { public: Foo( int x ) ...
754 0
【C++学习】显式构造函数
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.什么是显式构造函数? 首先要理解什么是隐式构造函数,并且弄清它的优缺点。 #include using std::cout; using std::endl; class complex...
616 0
【C++学习】valarray函数库
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 做毕设时碰到了最小二乘法的直线拟合问题,发觉C++里有以下这么几个类在做这件事情、以及后续处理时挺不错的,其实用OpenCV的数据结构和方法也可以进行,稍后研究一下。
487 0
【C++学习】const关键字释疑
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 我们先看看以下代码: #include int main() { const int a = 1; a = 2; printf("%d/n", a); return 0; } 你一看就知道这个一定在编译的时候报错:assignment of read-only variable a。
539 0
【C++学习】字符串处理
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.思维导图: Example1: char *strcpy(char *target, const char *source) {   char *...
655 0
IBM RSA (IBM rational software architect ) V8 学习之四 C++类图转换成c++代码
原文http://blog.csdn.net/ztz0223/article/details/7596025   前一讲: RSA建模 c++类图 已经说过了,如何生成一个结构体,添加成员变量,添加带参数的成员函数,那么如何看到效果呢? 这就是本文要说的了:变换->UML to C++ 回忆一下,之前建立的模型--c++类图。
1525 0
IBM RSA (IBM rational software architect ) V8 学习之六 C++类模板设计
原文http://blog.csdn.net/ztz0223/article/details/7603041   前面已经讲述过了IBM RSA (IBM rational software architect ) V8(具体版本V8.
955 0
+关注
贾志刚
2004毕业于山东大学齐鲁软件学院,软件工程专业。主要专注于图像处理算法学习与研究,计算机视觉技术开发应用,深度学习在计算机视觉领域应用。两本书籍《Java数字图像处理-编程技巧与应用实践》、《OpenCV On Android编程实践》作者
文章
问答
文章排行榜
最热
最新
相关电子书
更多
继承与功能组合
立即下载
对象的生命期管理
立即下载
移动与复制
立即下载