MFC框架下,加密图片加载并显示功能

最近一直在更新Qt框架下的内容,这两天来总结下对MFC框架下的使用吧,上一章节介绍了QT框架下的图片功能,那么今天就继续来讲述下图片功能,在MFC框架下是如何实现加密图片的操作的。

前沿

在实际的工作中,如果你所做的产品主要是针对教学系列的,那么在软件使用过程中,对图片视频以及文档的资料保密性肯定要强一些,今天就来举例简单的例子吧,如何加载一张加密图片,并展示出来吧~

功能实现

开发环境:vs2010

既然要用MFC框架,咱们就从低版本的开始吧,毕竟高版本是兼容低版本的,不过也不能再低了,VC6.0咱肯定是不会用的~

无论是什么环境下,加载图片的过程无外乎是这种流程:

1:加载图片路径

2:使用对应的图片类进行转换

3:将转换后的类附着到显示位置

当前,对于加密图片来说也是同样的道理。

为了简单实现这里的图片打开类采用了CImage

CImage

该类提供增强的位图支持,包括加载和保存采用JPEG、GIF、BMP和可移植网络图形格式的图像(PNG)格式。

但是,在这里CImage有一个缺点,如果加载的图片与给定的位置不一致时,就会造成失真,真是一个很严重的问题。

如果想要实现特别炫酷的图片展示以及页面风格,可以采用GDI的方式,这里就不再过多说明,改天详细来讲解GDI如何加载图片吧!

加密图片加载过程

1:打开指定的文件,并判断是否图片有效

2:对指定图片进行解密操作

3:将二进制图片流转成CImage可识别的IStream流

4:读取的图片流映加载到CImage类中

5:释放流操作

6:图片展示

看着加载步骤很多,实际上操作起来不是很难,最难的步骤在于第三步,也是加载核心,有需要的可以小本本记录下哟~

功能1:打开文件

这里的打开文件并没有做任何的实际处理,只是为了判断该路径是否存在。

C++加载文件,或者是判断文件有效的方法很多,假设,我们这里使用CFile的方式为例子:

CFile  file;
if (file.Open(strFilename , CFile::modeRead) == FALSE)
{
	file.Close();
	VERIFY(!strFilename);
	return NULL;
}
else
	file.Close();

其实,我倒不是很喜欢用这种方式,每次还得打开文件,再关闭文件,在实际判断的时候我会采用:_access方式判断的。

功能2:解密操作

加解密类叫做:CArithmeticBase pBase;

具体的加解密方式不做过多说明

int nFileLen = 0;
unsigned char* fileInfo;
m_base.decodeFile(strFilename , L"" , nFileLen , fileInfo);

解密操作后,可以获取到图片文件的大小以及流信息,这里的二进制流采用了unsigned char*存储。

功能3:二进制流转换

到了功能核心的部分啦!

在CImage类中,接收的流只能是IStream,那么该如何将unsigned char*类型的二进制流转换成CImage可识别的流信息呢?

第一步:根据解析的文件大小分配一块内存
HGLOBAL  hGlobal = GlobalAlloc(GMEM_MOVEABLE ,nFileLen);

在分配内容的时候,一般都采用GMEM_MOVEABLE可移动方式。比如说当堆中有很多一小块一小块的内存时,当再申请一块比较大的内存时,操作系统就会移动带有GMEM_MOVEABLE标识的内容合并出一块大内存出来。

所以,在使用具有GMEM_MOVEABLE标识的内存时,不能用内存地址做标识,而是要用返回的句柄做标识,这一点非常重要,否则崩溃了,你可就找错误吧!

第二步:锁定对象,并返回该对象的第一个字节指针
void *pData = GlobalLock(hGlobal);
memcpy(pData , fileInfo , nFileLen);
GlobalUnlock(hGlobal);

唯一需要注意的是:上锁后一定要解锁,这是使用C++比较麻烦的地方。

第三步:从内存中创建流对象
IStream   *pStream = NULL;
if (CreateStreamOnHGlobal(hGlobal , TRUE , &pStream) == S_OK)
{
    //流加载成功
}
else
{
    //加载失败
}
功能4:流对象加载到CImage

只有第三步正确加载流对象之后,才能将流对象加载到CImage中。

image.Load(pStream);

加载流信息后,将CImage返回给外部调用地方,在这里可以使用&的方式将CImage对象返回出去。

功能5:释放流对象

无论是否加载成功,只要在内存中创建了流对象,就必须要在最后进行销毁,以及内存的销毁。

pStream->Release();
GlobalFree(hGlobal);
功能6:图片展示

到这一步就已经将加密的图片资源变成了程序可识别的CImage类,假设我们在onpaint中加载图片资源

m_Image.Draw(pDC->GetSafeHdc(),rect);

到这里,一个完整的加密图片流程已经实现完成了。

总结

对于这一部分图片加载来说,功能不难,CImage::load方式可以直接加载图片,难点就在于加密图片,读取文件的时候不再是任何图片格式,不再是简单的加载路径的方式,而是采用字符流的方式,这里涉及到了内存分配以及加锁解密等底层操作。

当我们看到代码的时候就会觉得,原来是这么简单,实际上难的如何将二进制流转换成可识别的流信息。

我是糯诺诺米团,一名C++开发程序媛~

你可能感兴趣的:(MFC,mfc,c++)