CImage 从内存中读取图像
来源:互联网 发布:c语言指针教学视频 编辑:程序博客网 时间:2024/05/22 08:23
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);
阅读全文
1 0
- CImage 从内存中读取图像
- MFC CImage 读取图像 像素
- 从数据库中读取图像
- 从缓存中读取图像
- CImage读取8位灰度图像数据
- 在VC上实现如何从内存中读取JPEG、GIF等图像
- 在VC上实现如何从内存中读取JPEG、GIF等图像
- 在VC上实现如何从内存中读取JPEG、GIF等图像
- 在VC上实现如何从内存中读取JPEG、GIF等图像
- MFC中显示图像的类CImage
- MFC中显示图像的类CImage
- opencv从文件中批量读取图像
- 从摄像头中读取图像 OpenCV
- opencv从文件中批量读取图像
- CImage从资源中加载图片文件
- CImage从资源中加载图片文件
- CImage从资源中加载图片文件
- CImage实现jpeg到bmp内存图像转换
- printf 格式化输出符号详细说明
- 微信浏览器中location.href失效的问题
- 欢迎使用CSDN-markdown编辑器
- 13带更新的游标
- CAS 登录一个app1 了,点击App 2还是要登录,没法无缝登录
- CImage 从内存中读取图像
- MYSQL安装出现问题(The service already exists)
- 每个cpu 都有一个idle进程.
- Ubuntu下apt-get方式Git的安装、配置和更新
- Redhat7安装VNC服务端和FTP服务端实现远程控制
- hadoop mapTask执行过程
- 14动态游标
- 两种数组去重的方法
- mysql 查询排名