在MFC中怎么用SOCKET将屏幕截图压缩发送?急~~~~~~~

时间:2022-10-02 15:23:48
我想写一个远程监控程序,但是图片编码一点都不了解,急求获取屏幕截图并压缩成JPEG格式并存到char*中,并在服务器接收后显示出来的几个函数!急 啊  最好直接给源代码,没时间研究了~~~~急用!!!!!!!!!

13 个解决方案

#1


沙发自己占了~我的邮箱是381216292@qq.com 谁有资源跪求发一个啊!!急用 各位大侠

#2


这不是一个问题,是三个问题:截图 压缩 发送
发送和socket有关,其他的无关

#3


主要是截图 压缩!然后 得到的压缩图片怎么转成数据流··这几个东西从来没接触过啊!

#4


大侠们 求赐教啊~~~~~

#5


给个思路,分三步:1.屏幕截图,构造一个Cimage对象;2用Cimage的save方法进行压缩;3.用socket传送。

#6


我知道要截图 压缩 发送 但是具体的实现我找不到资料啊  你说的Cimage我也没研究过!我是这两天就要搞定的啊!没时间去从头研究,要不然就直接找书去看图片编码了。 各位大仙 救命啊!!!!!!!!!!

#7


截图好说,网上都是,实在不行模拟截图按钮也行;压缩的话,既然很急,可以考虑用FreeImage图形处理库(网上下载)

#8


截图截取BMP格式的 网上资料很多,我模仿者写了个函数,现在最麻烦的就是怎么转换成JPEG格式和如何将图片用SOCKET发送 因为SOCKET发送的是char*类型的;

#9


不一定要转JPG,既然压缩,JPG压缩肯定不如gzip压缩得好

用gzip压缩后就是一个char数组

#10



/******************************************************
函数功能:内存画图,图片压缩存储
输入参数:
输出参数:
返 回 值:
注:频道1 画图函数
该函数实现:
1:创建内存设备句柄,并与物理DC关联
2:读取磁盘上的图片文件到内存中,并画在内存DC中
3:把内存DC中的图片显示到物理DC中
4:把内存中的图片转换为JPG格式并存储到一块连续的内存区域
5:把4中连续的内存区域拷贝到频道1发送缓冲区中
******************************************************/
void CCh1View::Ch1Draw(void)
{
if(m_ServerStart==TRUE)
{  
CDocument* pDoc = GetDocument();

//获得频道1物理DC指针
m_pDC1=GetDC();

//创建内存DC
m_MemDC1.CreateCompatibleDC(NULL);

//获得文档类指针
m_pDoc = (CServerDoc*)GetDocument();

//释放文档类的位图1资源
m_pDoc->m_Bmp1.DeleteObject();   

//创建与频道1物理DC关联的位图
m_pDoc->m_Bmp1.CreateCompatibleBitmap(m_pDC1,320,240);

//获得位图的句柄
HBITMAP hBitmap=HBITMAP(m_pDoc->m_Bmp1);

//把该位图选入内存DC
HGDIOBJ hOldBMP=::SelectObject(m_MemDC1,hBitmap); 

//加载选中图片到内存
if(m_ImagePath==_T("default"))
{
m_Picture.Load(IDR_DEFAULT,_T("JPG"));
}
else
{
   m_Picture.Load(m_ImagePath);
}
    
m_Picture.UpdateSizeOnDC(&m_MemDC1);

//把图片画在内存DC中
m_Picture.Show(&m_MemDC1, CPoint(0,0), CPoint(320,240), 0,0);

//把内存DC中的图片拷贝到物理DC中显示出来
m_pDC1->BitBlt(0,0,320,240,&m_MemDC1,0,0,SRCCOPY);

//释放资源
m_Picture.FreePictureData();

//获得内存中上述位图的句柄
hBitmap=(HBITMAP)::SelectObject(m_MemDC1,hOldBMP);  

//将GDI+中的CImage对象与上述位图关联
m_Image.Attach(hBitmap); 

//初始化流对象
IStream*   pStmImage=NULL; 

//申请可移动的缓冲区 
HGLOBAL   hMemBmp=GlobalAlloc(GMEM_MOVEABLE,0);
if(hMemBmp==NULL)   
{
return;
}

//将可移动缓冲区作为流的起始 
CreateStreamOnHGlobal(hMemBmp,FALSE,&pStmImage);
if(pStmImage==NULL) 

GlobalFree(hMemBmp); 
return; 


//把位图转换为JPG格式并保存在流对象缓冲区中
m_Image.Save(pStmImage,Gdiplus::ImageFormatJPEG); 

//得到缓冲区的起始地址
BYTE*   pbyBmp=(BYTE*)GlobalLock(hMemBmp); 

//锁住内存
GlobalUnlock(hMemBmp);

//得到格式转换后图片的大小
m_BufferSize=GlobalSize(hMemBmp);

//把内存中的JPG格式图片数据拷贝到频道1发送缓冲区中
memcpy((void*)m_Buffer,(void*)pbyBmp,m_BufferSize);

//释放流对象资源
pStmImage-> Release(); 

//释放可移动缓冲区资源
GlobalFree(hMemBmp); 

//销毁CImage对象
if(m_Image) 
{
m_Image.Destroy(); 
}

//删除内存DC
m_MemDC1.DeleteDC();

//删除物理DC
m_pDC1->DeleteDC();
}
}


头文件中的变量以及函数

private:
//频道1 CImage对象,用户在内存中进行图片压缩(使用GDI+)
CImage m_Image;  

//用于加载图片和显示图片
CPicture m_Picture;    

//频道1物理DC的指针
CDC* m_pDC1;     

//频道1内存DC
CDC m_MemDC1;       

//文档类指针
CServerDoc* m_pDoc;         

//位图句柄
HBITMAP m_hBitmap;   

//图片路径
CString m_ImagePath;     

//频道1缓冲区
BYTE m_Buffer[65536]; 

//缓冲区实际大小
SIZE_T m_BufferSize;

public:
//服务器是否开启
BOOL m_ServerStart;

public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
void Ch1Draw(void);


绝对可以使用的源代码。功能:取View1 每秒25帧(压缩成JPG格式) 通过UDP发出

#11


建议看下RDP远程桌面协议

#12


悲剧,我用的是VC6.0 不支持CImage 也没有atlimage.h库!尴尬啊····

#13


只求能用VC6.0能实现的将BMP格式转成JPEG格式的,能实现分就送出去结贴了~~~~~~~~我现在已经得到一个BITMAP作为函数返回值的图片信息。

#1


沙发自己占了~我的邮箱是381216292@qq.com 谁有资源跪求发一个啊!!急用 各位大侠

#2


这不是一个问题,是三个问题:截图 压缩 发送
发送和socket有关,其他的无关

#3


主要是截图 压缩!然后 得到的压缩图片怎么转成数据流··这几个东西从来没接触过啊!

#4


大侠们 求赐教啊~~~~~

#5


给个思路,分三步:1.屏幕截图,构造一个Cimage对象;2用Cimage的save方法进行压缩;3.用socket传送。

#6


我知道要截图 压缩 发送 但是具体的实现我找不到资料啊  你说的Cimage我也没研究过!我是这两天就要搞定的啊!没时间去从头研究,要不然就直接找书去看图片编码了。 各位大仙 救命啊!!!!!!!!!!

#7


截图好说,网上都是,实在不行模拟截图按钮也行;压缩的话,既然很急,可以考虑用FreeImage图形处理库(网上下载)

#8


截图截取BMP格式的 网上资料很多,我模仿者写了个函数,现在最麻烦的就是怎么转换成JPEG格式和如何将图片用SOCKET发送 因为SOCKET发送的是char*类型的;

#9


不一定要转JPG,既然压缩,JPG压缩肯定不如gzip压缩得好

用gzip压缩后就是一个char数组

#10



/******************************************************
函数功能:内存画图,图片压缩存储
输入参数:
输出参数:
返 回 值:
注:频道1 画图函数
该函数实现:
1:创建内存设备句柄,并与物理DC关联
2:读取磁盘上的图片文件到内存中,并画在内存DC中
3:把内存DC中的图片显示到物理DC中
4:把内存中的图片转换为JPG格式并存储到一块连续的内存区域
5:把4中连续的内存区域拷贝到频道1发送缓冲区中
******************************************************/
void CCh1View::Ch1Draw(void)
{
if(m_ServerStart==TRUE)
{  
CDocument* pDoc = GetDocument();

//获得频道1物理DC指针
m_pDC1=GetDC();

//创建内存DC
m_MemDC1.CreateCompatibleDC(NULL);

//获得文档类指针
m_pDoc = (CServerDoc*)GetDocument();

//释放文档类的位图1资源
m_pDoc->m_Bmp1.DeleteObject();   

//创建与频道1物理DC关联的位图
m_pDoc->m_Bmp1.CreateCompatibleBitmap(m_pDC1,320,240);

//获得位图的句柄
HBITMAP hBitmap=HBITMAP(m_pDoc->m_Bmp1);

//把该位图选入内存DC
HGDIOBJ hOldBMP=::SelectObject(m_MemDC1,hBitmap); 

//加载选中图片到内存
if(m_ImagePath==_T("default"))
{
m_Picture.Load(IDR_DEFAULT,_T("JPG"));
}
else
{
   m_Picture.Load(m_ImagePath);
}
    
m_Picture.UpdateSizeOnDC(&m_MemDC1);

//把图片画在内存DC中
m_Picture.Show(&m_MemDC1, CPoint(0,0), CPoint(320,240), 0,0);

//把内存DC中的图片拷贝到物理DC中显示出来
m_pDC1->BitBlt(0,0,320,240,&m_MemDC1,0,0,SRCCOPY);

//释放资源
m_Picture.FreePictureData();

//获得内存中上述位图的句柄
hBitmap=(HBITMAP)::SelectObject(m_MemDC1,hOldBMP);  

//将GDI+中的CImage对象与上述位图关联
m_Image.Attach(hBitmap); 

//初始化流对象
IStream*   pStmImage=NULL; 

//申请可移动的缓冲区 
HGLOBAL   hMemBmp=GlobalAlloc(GMEM_MOVEABLE,0);
if(hMemBmp==NULL)   
{
return;
}

//将可移动缓冲区作为流的起始 
CreateStreamOnHGlobal(hMemBmp,FALSE,&pStmImage);
if(pStmImage==NULL) 

GlobalFree(hMemBmp); 
return; 


//把位图转换为JPG格式并保存在流对象缓冲区中
m_Image.Save(pStmImage,Gdiplus::ImageFormatJPEG); 

//得到缓冲区的起始地址
BYTE*   pbyBmp=(BYTE*)GlobalLock(hMemBmp); 

//锁住内存
GlobalUnlock(hMemBmp);

//得到格式转换后图片的大小
m_BufferSize=GlobalSize(hMemBmp);

//把内存中的JPG格式图片数据拷贝到频道1发送缓冲区中
memcpy((void*)m_Buffer,(void*)pbyBmp,m_BufferSize);

//释放流对象资源
pStmImage-> Release(); 

//释放可移动缓冲区资源
GlobalFree(hMemBmp); 

//销毁CImage对象
if(m_Image) 
{
m_Image.Destroy(); 
}

//删除内存DC
m_MemDC1.DeleteDC();

//删除物理DC
m_pDC1->DeleteDC();
}
}


头文件中的变量以及函数

private:
//频道1 CImage对象,用户在内存中进行图片压缩(使用GDI+)
CImage m_Image;  

//用于加载图片和显示图片
CPicture m_Picture;    

//频道1物理DC的指针
CDC* m_pDC1;     

//频道1内存DC
CDC m_MemDC1;       

//文档类指针
CServerDoc* m_pDoc;         

//位图句柄
HBITMAP m_hBitmap;   

//图片路径
CString m_ImagePath;     

//频道1缓冲区
BYTE m_Buffer[65536]; 

//缓冲区实际大小
SIZE_T m_BufferSize;

public:
//服务器是否开启
BOOL m_ServerStart;

public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
void Ch1Draw(void);


绝对可以使用的源代码。功能:取View1 每秒25帧(压缩成JPG格式) 通过UDP发出

#11


建议看下RDP远程桌面协议

#12


悲剧,我用的是VC6.0 不支持CImage 也没有atlimage.h库!尴尬啊····

#13


只求能用VC6.0能实现的将BMP格式转成JPEG格式的,能实现分就送出去结贴了~~~~~~~~我现在已经得到一个BITMAP作为函数返回值的图片信息。