当前位置: 首页 > article >正文

CImage 从内存中读取图像

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);
http://www.lryc.cn/news/2416478.html

相关文章:

  • FileZilla Server简介及使用说明
  • 解决Adobe reader 8 突然打不开了并报许可协议的问题
  • 2023年【A特种设备相关管理(锅炉压力容器压力管道)】报名考试及A特种设备相关管理(锅炉压力容器压力管道)模拟考试题
  • vue 项目如何捕获awit 错误情况
  • 可行性分析与需求分析 —以图书馆管理系统为例
  • 破解密码的8种典型手段与防护建议
  • Linux service network服务重启失败及ping不通外网解决办法
  • linux 多媒体安装和使用
  • cnna词汇集(三)
  • CreateProcess失败返回错误代码998
  • 0x0000007B是什么意思?解决方案
  • 43张图详解计算机网络,看这一篇就够了
  • C语言中,事件对象(CreateEvent)、互斥对象(CreateMutex)、关键代码段(InitializeCriticalSection)
  • 量子通信和传统通信的对比分析
  • keil报错:Loading PDSC Debug Description failed for STMicroelectronics STM32Fxxxxxxx
  • php ismethod,PHP的method_exists,function_exists,is_callable的区别
  • linux ioctl 函数
  • #SATA# SATA 专业术语
  • 工作流引擎 介绍
  • 权限持久化---映像劫持检测(Shift后门)
  • 【金士顿PS2251-03(PS2303)量产教程_2024】
  • Winedit修改快捷键
  • 推荐一款强大的Go语言工具:goid
  • GitHub Pages + Jekyll 快速搭建个人博客网站
  • JavaScript(BOM)中Window对象的prompt()方法
  • 注意力机制总结
  • windows配置防火墙
  • Sōsh:让宅男宅女从虚拟回到现实的社交网站
  • 一秒教你保存浏览器当前页面的所有图片
  • 若要使他人能够在远程计算机上查看此特定错误消息的详细信息,请在位于当前 Web 应用程序根目录下的“web.config”配置文件中创建一个 customErrors 标记。然后应将此 cust