CImage 的CImage::Load( IStream* pStream) 从内存中读取图像时,需要提供实现了IStream的对象。一般都是采用CreateStreamOnHGlobal创建IStream对象,但这需要重新分配内存,再将内存中图像复制到新分配的内存中,完了还要释放,多了很多操作,也影响性能。
下面这个类就是实现了IStream,可以实现从内存直接读取图像,省了上述多余的操作。

Stream.h文件

#pragma once
#include <windows.h>
class CStream : public IStream
{
public:// // IUnknown members // HRESULT __stdcall QueryInterface(REFIID iid, void ** ppvObject);ULONG   __stdcall AddRef(void);ULONG   __stdcall Release(void);// // ISequentialStream members // HRESULT __stdcall Read(void *pv, ULONG cb, ULONG *pcbRead);HRESULT __stdcall Write(const void *pv, ULONG cb, ULONG *pcbWritten);// // IStream members // HRESULT __stdcall Seek(LARGE_INTEGER  dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition);HRESULT __stdcall SetSize(ULARGE_INTEGER libNewSize);HRESULT __stdcall CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);HRESULT __stdcall Commit(DWORD grfCommitFlags);HRESULT __stdcall Revert(void);HRESULT __stdcall LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);HRESULT __stdcall UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);HRESULT __stdcall Stat(STATSTG *pstatstg, DWORD grfStatFlag);HRESULT __stdcall Clone(IStream **ppstm);// // Constructor / Destructor // CStream(BYTE *pData, ULONG nSize);~CStream();private:// // private members and functions // LONG            m_lRefCount;STATSTG         m_statstg;          // each IStream needs one of these ULARGE_INTEGER  m_nOffset;          // offset within the stream ULARGE_INTEGER  m_nLength;          // length of the stream BYTE*           m_pData;            // stream data from
};

Stream.cpp文件

//
//  IStream.cpp
//  Implementation of the IStream COM interface
//
#include "stdafx.h"
#include "Stream.h"#define DEFNAME L"Memory IStream" //
//  Constructor
//
CStream::CStream(BYTE *pData, ULONG nSize)
{m_lRefCount = 1;m_pData = pData;// stream metrics m_nOffset.QuadPart = 0;m_nLength.QuadPart = nSize;//len; // stream status m_statstg.type = STGTY_STREAM;      // IStream object m_statstg.cbSize.QuadPart = 0;//len;                // Set to the length of our stream object m_statstg.grfLocksSupported = 0;                // Region locking not supported m_statstg.grfMode = 0;              // access mode m_statstg.clsid = CLSID_NULL;       // not used for IStreams m_statstg.grfStateBits = 0;             // not used for IStreams m_statstg.reserved = 0;             // reserved for CoFileTimeNow(&m_statstg.ctime);                // creation time CoFileTimeNow(&m_statstg.atime);                // last access time CoFileTimeNow(&m_statstg.mtime);                // last modify time
}//
//  Destructor
//
CStream::~CStream()
{
}//
//  IUnknown::AddRef
//
ULONG __stdcall CStream::AddRef(void)
{// increment object reference count return InterlockedIncrement(&m_lRefCount);
}//
//  IUnknown::Release
//
ULONG __stdcall CStream::Release(void)
{// decrement object reference count LONG count = InterlockedDecrement(&m_lRefCount);if (count == 0){delete this;return 0;}else{return count;}
}//
//  IUnknown::QueryInterface
//
HRESULT __stdcall CStream::QueryInterface(REFIID iid, void **ppvObject)
{// check to see what interface has been requested if (iid == IID_IStream || iid == IID_IUnknown || iid == IID_ISequentialStream){AddRef();*ppvObject = this;return S_OK;}else{*ppvObject = 0;return E_NOINTERFACE;}
}//
//  ISequentialStream::Read
//
HRESULT __stdcall CStream::Read(void *pv, ULONG cb, ULONG *pcbRead)
{ULONG available;if (pv == 0)return STG_E_INVALIDPOINTER;available = min(cb, (ULONG)(m_nLength.QuadPart - m_nOffset.QuadPart));memcpy(pv, m_pData + m_nOffset.QuadPart, available);m_nOffset.QuadPart += available;if (pcbRead)*pcbRead = available;return S_OK;
}//
//  ISequentialStream::Write
//
HRESULT __stdcall CStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten)
{if (pv == 0)return STG_E_INVALIDPOINTER;return E_NOTIMPL;
}//
//  IStream::Seek
//
HRESULT __stdcall CStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{switch (dwOrigin){case STREAM_SEEK_SET:   m_nOffset.QuadPart = dlibMove.QuadPart;                      break;case STREAM_SEEK_CUR:   m_nOffset.QuadPart = m_nOffset.QuadPart + dlibMove.QuadPart; break;case STREAM_SEEK_END:   m_nOffset.QuadPart = m_nLength.QuadPart - dlibMove.QuadPart; break;}if (plibNewPosition)*plibNewPosition = m_nOffset;return S_OK;
}//
//  IStream::SetSize
//
HRESULT __stdcall CStream::SetSize(ULARGE_INTEGER libNewSize)
{return S_OK;
}//
//  IStream::CopyTo
//
HRESULT __stdcall CStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{DWORD len, written;len = (ULONG)min(cb.QuadPart, m_nLength.QuadPart);pstm->Write(m_pData, len, &written);if (pcbRead)pcbRead->QuadPart = len;if (pcbWritten)pcbWritten->QuadPart = written;return S_OK;
}//
//  IStream::Commit
//
HRESULT __stdcall CStream::Commit(DWORD grfCommitFlags)
{// Transacted mode is not supported return S_OK;
}//
//  IStream::Revert
//
HRESULT __stdcall CStream::Revert()
{// Transacted mode is not supported return S_OK;
}//
//  IStream::LockRegion
//
HRESULT __stdcall CStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{// locking is not supported return STG_E_INVALIDFUNCTION;
}//
//  IStream::UnlockRegion
//
HRESULT __stdcall CStream::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{// locking is not supported return STG_E_INVALIDFUNCTION;
}//
//  IStream::Stat
//
HRESULT __stdcall CStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
{if (pstatstg == 0)return STG_E_INVALIDPOINTER;// return our STATSTG to the caller m_statstg.cbSize.QuadPart = m_nLength.QuadPart;*pstatstg = m_statstg;switch (grfStatFlag){case STATFLAG_DEFAULT:// allocate a new buffer for the name if ((pstatstg->pwcsName = (WCHAR *)CoTaskMemAlloc(sizeof(DEFNAME))) == 0)return STG_E_INSUFFICIENTMEMORY;lstrcpyW(pstatstg->pwcsName, DEFNAME);break;case STATFLAG_NONAME:pstatstg->pwcsName = 0;break;default:return STG_E_INVALIDFLAG;}return S_OK;
}//
//  IStream::Clone
//
HRESULT __stdcall CStream::Clone(IStream **ppstm)
{return E_NOTIMPL;
}

使用就很简单了:
BYTE* pData ; // 图像数据
DWORD nSize; // 图像数据的长度

CStream stream(pData, nSize);
CImage img;
img.Load(&stream);

CImage 从内存中读取图像相关推荐

  1. 在内存中读取函数的ShellCode并执行

    在内存中读取函数的ShellCode并执行 下面是一个例子,实现的效果是将fun1函数的十六进制读取出来,在内存中将str1的地址改成str2,分配一块内存,将改好的函数的ShellCode写入并执行 ...

  2. python读取图像数据流_浅谈TensorFlow中读取图像数据的三种方式

    本文面对三种常常遇到的情况,总结三种读取数据的方式,分别用于处理单张图片.大量图片,和TFRecorder读取方式.并且还补充了功能相近的tf函数. 1.处理单张图片 我们训练完模型之后,常常要用图片 ...

  3. ffmpeg 从内存中读取数据(或将数据输出到内存)

    更新记录(2014.7.24): 1.为了使本文更通俗易懂,更新了部分内容,将例子改为从内存中打开. 2.增加了将数据输出到内存的方法. 从内存中读取数据 ffmpeg一般情况下支持打开一个本地文件, ...

  4. C# 操作地址 从内存中读取写入数据(初级)

    本示例以植物大战僵尸为例, 实现功能为 每1秒让阳光刷新为 9999.本示例使用的游戏版本为 [植物大战僵尸2010年度版], 使用的辅助查看内存地址的工具是  CE. 由于每次启动游戏, 游戏中阳光 ...

  5. opencv从内存缓冲区中读取图像数据

    1.从内存中加载图像数据 s_Image_Info stDispImgInfo = spImgInfo->m_stDispInfo; //cv::_InputArray pic_arr(stDi ...

  6. 查看mysql是否内存中读取数据_MySQL中的内存临时表

    //MySQL中的内存临时表// 这两天事情稍微有点多,公众号也停止更新了几天,结果有读者催更了,也是,说明还是有人关注,利己及人,挺好. 今天分享的内容是MySQL中的临时表,对于临时表,之前我其实 ...

  7. TensorFlow中读取图像数据的三种方式(转)

    附加一个链接关于DatasetAPI:https://zhuanlan.zhihu.com/p/30751039 本文面对三种常常遇到的情况,总结三种读取数据的方式,分别用于处理单张图片.大量图片,和 ...

  8. c语言中读取内存的文件,c++从内存中读取文件内容,内容写到内存 实现文件的内存共享代码实例...

    使用c++代码进行内存共享操作,内存共享可以通过key value的形式来保存内存,后面可以使用key值来直接读取内存,效率会很高/ 函数说明: shmget(key_t key, size_t si ...

  9. vb.net 如何从文件中读取图像

        Public Function GetImageFromFile()Function GetImageFromFile(ByVal pstrFileName As String) As Boo ...

  10. LCD不带显存,是如何内存映射屏幕。S5PV210SoC在内存中选一段内存存放颜色数据,通过配置将LCD控制器和这一段内存连接起来,构成映射关系,LCD控制器就自动从显存中读取像素数据传给LCD驱动器

    一.LCD控制原理 S5PV210处理器中自带LCD控制器,控制LCD的显示,把 LCD 图像数据从一个位于系统内存的 video buffer 传送到一个外部的 LCD 驱动器接口. 类型: STN ...

最新文章

  1. 网站内容才是SEO的第一要素
  2. 简单一招搞定 three.js 屏幕适配
  3. 深入浅出python机器学习_3.3.1_对数据集进行分析
  4. 前端_JavaScript_面向对象编程
  5. J.U.C 提供的阻塞队列
  6. java中的%nf_java中DecimalFormat四舍五入用法详解
  7. 【算法系列之一】二叉树最小深度
  8. from rfc 2068 hypertext怎么解决_“饮水思源”英语怎么翻译
  9. 多租户系统技术优越性及架构选型---springCloud工作笔记167
  10. Hibernate相关内容
  11. 广告投放系统数据表设计
  12. MyBatis Mapper.xml的choose/case标签详解
  13. 苹果cms模板_苹果cmsv10高端模板有哪些?
  14. forever保护node server进程报错(node:8156) Warning: Accessing non-existent property ‘padLevels‘ of module e
  15. 安卓面试宝典,2021最新Android知识体系总结,面试资料分享
  16. Word页眉设置不同的文字,但是页码按照顺序不变
  17. 手把手教你怎么批量压缩视频文件
  18. Blender图解教程:设置参考图
  19. C++中使用map时,it->second是什么意思?
  20. mysql查询选修课程的学生_[MySQL]查询学生选课的情况(一)

热门文章

  1. QT的Q3DScatter使用(三维可视图)
  2. mysql定时导出数据_mysql定时备份数据
  3. 极值波延拓matlab函数,函数极值是什么意思
  4. 如何实现某个软件的单独断网/稳定地解决fluent断网计算中止问题/tecplot联网后打开程序出现报错问题
  5. uniapp uView 微信小程序弹框二维码canvas不显示,以及显示后跟随滑动的问题
  6. 数据结构/排序/归并排序/二路归并排序
  7. 云台测试软件,三轴云台校准工具
  8. 什么软件测试cpu满载,截然相反!CPU满载压力测试
  9. 【企业微信点餐系统】
  10. 人脸数据库使用授权求助帖