CImage 如何实现内存bmp数据转换成jpeg数据

luckyboy101 2009-11-09 01:39:36
CWindowDC dc(NULL);
CBitmap bm;
CRect rect(0,0,::GetSystemMetrics(SM_CXSCREEN),::GetSystemMetrics(SM_CYSCREEN));
int Width=rect.Width();
int Height=rect.Height();
bm.CreateCompatibleBitmap(&dc,Width,Height);
CDC tdc;
tdc.CreateCompatibleDC(&dc);
CBitmap*pOld=tdc.SelectObject(&bm);
tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);//截取屏幕数据bmp到bm里
CImage *image=new CImage;
image->Attach(bm);
image->Save(L"e:\\picttest%d.jpg");//bmp数据转换成jpeg保存到文件
最后一句实现了bmp数据转换成jpeg保存到文件,我想实现内存bmp数据转换成jpeg数据,并不需要保存为文件,如何实现?
...全文
1087 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
NEW_ONE_GAY 2011-06-08
  • 打赏
  • 举报
回复
收藏 3Q
MoXiaoRab 2009-11-10
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 jameshooo 的回复:]
我晕,LaoWu_ 赚翻了,我一分没得到,哭……
[/Quote]
哈哈
luckyboy101 2009-11-09
  • 打赏
  • 举报
回复
晕,分给错了
jameshooo 2009-11-09
  • 打赏
  • 举报
回复
我晕,LaoWu_ 赚翻了,我一分没得到,哭……
luckyboy101 2009-11-09
  • 打赏
  • 举报
回复
搞定了
把pStream1->Read(p,size,&nRead); 该成pStream1->Write(p,size,&nRead);
非常感谢
jameshooo
luckyboy101 2009-11-09
  • 打赏
  • 举报
回复
image->Attach(bm);
IStream* pStream = NULL;
CreateStreamOnHGlobal(NULL, TRUE, &pStream);
image->Save(pStream,ImageFormatJPEG);

HGLOBAL hGlobal = NULL;
GetHGlobalFromStream(pStream, &hGlobal); // 获取 IStream 的内存句柄
LPBYTE pBits = (LPBYTE)GlobalLock(hGlobal); // pBits 就是存储JPEG内容的内存指针
DWORD size=(DWORD)GlobalSize(pBits);



IStream* pStream1 = NULL;
CreateStreamOnHGlobal(NULL, TRUE, &pStream1);

BYTE *p,*p2;
HANDLE hDib=GlobalAlloc(GMEM_MOVEABLE,size);
p=(LPBYTE)GlobalLock(hDib);
p2=p;
char *buf;
int US_MAXSIEZ=1024;
buf=new char[US_MAXSIEZ];
for(WORD i=0;i<size/US_MAXSIEZ;i++)
{
CopyMemory(buf,pBits+US_MAXSIEZ*i,US_MAXSIEZ);
CopyMemory(p2,buf,US_MAXSIEZ);
p2=p2+US_MAXSIEZ;
}
if(size%US_MAXSIEZ)
{
CopyMemory(buf,pBits+US_MAXSIEZ*(size/US_MAXSIEZ-1),size%US_MAXSIEZ);
CopyMemory(p2,buf,size%US_MAXSIEZ);
p2=p2+size%US_MAXSIEZ;
}
ULONG nRead=0;
pStream1->Read(p,size,&nRead);

CImage *image1=new CImage;
image1->Load(pStream1);
CDC *pdc=GetDC();
image1->Save(L"e:\\2.jpg");
我通过模拟发送jpeg数据,结果不对,问题出在哪?
jameshooo 2009-11-09
  • 打赏
  • 举报
回复
已经说过了,数据大小通过GlobleSize得到,或者通过IStream::Stat也能得到。
luckyboy101 2009-11-09
  • 打赏
  • 举报
回复
CWindowDC dc(NULL);
CBitmap bm;
CRect rect(0,0,::GetSystemMetrics(SM_CXSCREEN),::GetSystemMetrics(SM_CYSCREEN));
int Width=rect.Width();
int Height=rect.Height();
bm.CreateCompatibleBitmap(&dc,Width,Height);
CDC tdc;
tdc.CreateCompatibleDC(&dc);
CBitmap*pOld=tdc.SelectObject(&bm);
tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);
CImage *image=new CImage;
image->Attach(bm);
IStream* pStream = NULL;
CreateStreamOnHGlobal(NULL, TRUE, &pStream);
image->Save(pStream,ImageFormatJPEG);

HGLOBAL hGlobal = NULL;
GetHGlobalFromStream(pStream, &hGlobal); // 获取 IStream 的内存句柄
LPBYTE pBits = (LPBYTE)GlobalLock(hGlobal); // pBits 就是存储JPEG内容的内存指针

IStream* pStream1 = NULL;
CreateStreamOnHGlobal(NULL, TRUE, &pStream1);
*****************************
如何把pStream数据发送到pStream1,数据大小如何得到//pStream1=pStream;
****************************

CImage *image1=new CImage;
image1->Load(pStream1);
CDC *pdc=GetDC();
image1->Draw((HDC)*pdc,0,0);
jameshooo 2009-11-09
  • 打赏
  • 举报
回复
可以直接传输pBits,内存大小通过GlobleSize获得。

接收方处理是一样的,创建一个IStream,调用Write把数据写入,然后用IStream版本的CImage::Load方法加载
ToperRay 2009-11-09
  • 打赏
  • 举报
回复
学习,收藏。

zhenandxt 2009-11-09
  • 打赏
  • 举报
回复
学习学习
luckyboy101 2009-11-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 jameshooo 的回复:]
干嘛一定要用CImage呢,它公开的功能太少,直接用被它封装的Bitmap类,它的Save方法有几个版本,其中一个就是存储到IStream中,这个就是你需要的。

C/C++ codeusingnamespace Gdiplus;
...

Bitmap* pBmp= Bitmap::FromHBITMAP(bm, NULL);// 从HBITMAP创建一个Bitmap
IStream* pStream= NULL;
CreateStreamOnHGlobal(NULL, TRUE,&pStream);// 创建一个 IStream
CLSID jpgClsid;
GetEncoderClsid(L"image/jpeg",&jpgClsid);
pBmp->Save(pStream,&jpgClsid);// 把 Bitmap 的内容编码到 IStream 中
HGLOBAL hGlobal= NULL;
GetHGlobalFromStream(pStream,&hGlobal);// 获取 IStream 的内存句柄LPBYTE pBits= (LPBYTE)GlobalLock(hGlobal);// pBits 就是存储JPEG内容的内存指针// do something....

GlobalUnlock(hGlobal);
pStream->Release();
[/Quote]
我想把jpeg数据传输,那么是不是传输pBits就可以了,在接受方如何重建CImage?
MoXiaoRab 2009-11-09
  • 打赏
  • 举报
回复
IStream..好,很和谐
jameshooo 2009-11-09
  • 打赏
  • 举报
回复
纠正一下,CImage也提供了IStream的版本,可以不直接使用Bitmap了
_JeffreyWu 2009-11-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 jameshooo 的回复:]
干嘛一定要用CImage呢,它公开的功能太少,直接用被它封装的Bitmap类,它的Save方法有几个版本,其中一个就是存储到IStream中,这个就是你需要的。

C/C++ codeusingnamespace Gdiplus;
...

Bitmap* pBmp= Bitmap::FromHBITMAP(bm, NULL);// 从HBITMAP创建一个Bitmap
IStream* pStream= NULL;
CreateStreamOnHGlobal(NULL, TRUE,&pStream);// 创建一个 IStream
CLSID jpgClsid;
GetEncoderClsid(L"image/jpeg",&jpgClsid);
pBmp->Save(pStream,&jpgClsid);// 把 Bitmap 的内容编码到 IStream 中
HGLOBAL hGlobal= NULL;
GetHGlobalFromStream(pStream,&hGlobal);// 获取 IStream 的内存句柄LPBYTE pBits= (LPBYTE)GlobalLock(hGlobal);// pBits 就是存储JPEG内容的内存指针// do something....

GlobalUnlock(hGlobal);
pStream->Release();
[/Quote]

MARK.学习
jameshooo 2009-11-09
  • 打赏
  • 举报
回复
干嘛一定要用CImage呢,它公开的功能太少,直接用被它封装的Bitmap类,它的Save方法有几个版本,其中一个就是存储到IStream中,这个就是你需要的。


using namespace Gdiplus;
...

Bitmap* pBmp = Bitmap::FromHBITMAP(bm, NULL); // 从HBITMAP创建一个Bitmap

IStream* pStream = NULL;
CreateStreamOnHGlobal(NULL, TRUE, &pStream); // 创建一个 IStream

CLSID jpgClsid;
GetEncoderClsid(L"image/jpeg", &jpgClsid);
pBmp->Save(pStream, &jpgClsid); // 把 Bitmap 的内容编码到 IStream 中

HGLOBAL hGlobal = NULL;
GetHGlobalFromStream(pStream, &hGlobal); // 获取 IStream 的内存句柄
LPBYTE pBits = (LPBYTE)GlobalLock(hGlobal); // pBits 就是存储JPEG内容的内存指针
// do something
....

GlobalUnlock(hGlobal);
pStream->Release();

验证码识别 2009-11-09
  • 打赏
  • 举报
回复
HRESULT Save(
IStream* pStream,
REFGUID guidFileType
) const throw();

用这个函数应该可以吧
zpf82118 2009-11-09
  • 打赏
  • 举报
回复
CxImage
我的资源里有该库的源码
验证码识别 2009-11-09
  • 打赏
  • 举报
回复
mark
MoXiaoRab 2009-11-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 toperray 的回复:]
CMemoryFile

应该可以吧。


[/Quote]
加载更多回复(3)

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧