写点什么

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

  • 2022 年 9 月 15 日
    河北
  • 本文字数:1882 字

    阅读完需:约 6 分钟

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 方式可以直接加载图片,难点就在于加密图片,读取文件的时候不再是任何图片格式,不再是简单的加载路径的方式,而是采用字符流的方式,这里涉及到了内存分配以及加锁解密等底层操作。


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


我是中国好公民 st,一名 C++程序媛

发布于: 刚刚阅读数: 3
用户头像

书山有路勤为径,学海无涯苦作舟 2022.07.01 加入

擅长语言:C++ 涉及语言:Python

评论

发布
暂无评论
MFC框架下,加密图片加载并显示功能_c++_中国好公民st_InfoQ写作社区