您的位置:首页 > 其它

桌面共享中桌面图片对比取变化部分数据和还原显示

2010-07-12 15:11 387 查看
在做桌面共享时,最重要的就是桌面数据的对比压缩算法,怎么让数据在网络上传得最少而又不损耗桌面质量,有很多人直接用vnc的算法,但vnc虽然开源,又权威,但项目太大,看源码有点难看懂,前些天我实现了一个轻量级的算法,自己试了下,效果跟vnc不分上下,只是算法比较单一,不象vnc一个能适应不同的网络自动调整算法,下面来看下我的算法,分两部分

一、从一张图片中dif出变化部分数据,张桌面切成n个小正方形,比较每个正方形是否改变,如果改变则把整个正方形取出。

#define SETBIT(p, x) ((unsigned char)p[x/8] |= (1 << (x%8)))
static DWORD m_dwOutMaxSize;
static BYTE * m_lpOutBuffer;
static BYTE * m_lpPreData;

从一张图片中dif出变化部分图片转成一张jgeg图片

BYTE *BMPtoFix(unsigned char * lpInData,int w,int h, unsigned long *lWidth ,unsigned long *lHeight, unsigned long *lHeadSize, unsigned long *lSize)
{
/* //bmp图片头
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)lpInData;
//去头
lpInData += sizeof(BITMAPINFOHEADER);
//图片必须是24bit,否则退出
if (lpbi->biBitCount != 24){
return NULL;
}
int w = lpbi->biWidth;///<宽
int h = lpbi->biHeight;///<高
*/
if (w % 16){
return NULL;
}
int hCell = h/16;///<横向格数
/**如果不能整除则加一个格*/
if (hCell % 16) hCell++;
int wCell = w / 16;///<竖向格数
/**这里用char的每一位来表示一个格的状态,0为不变,1为要更新,
hSize用来表示头所占的字节数。
*/
int hSize = (wCell*hCell)/8;///<屏幕所有的格数/8 = char 个数
if ((wCell*hCell)%8){
hSize++;///<不能整除加一个char
}
BOOL bPre = true;
DWORD lBufSize = wCell*hCell*768 + hSize;///<构造这张图片在内存要用的大小,每一格16*16*3 = 768字节
/**分配全局内存,hSize + 图片数据*/
if (m_lpOutBuffer==NULL || m_dwOutMaxSize < lBufSize)
{
if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
m_dwOutMaxSize = lBufSize;///<替换当前最大内存值
if (m_lpOutBuffer == NULL){
return NULL;
}
memset(m_lpOutBuffer, 0, lBufSize);
}
/**分配全局内存,old图片数据*/
if (m_lpPreData==NULL)
{
m_lpPreData = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize-hSize);
if (m_lpPreData == NULL){
return NULL;
}
memset(m_lpPreData,0, lBufSize-hSize);
bPre = false;
}
BYTE *lpOutData = m_lpOutBuffer + hSize;///<用来存放输出的数据
DWORD lOutRowOffset = 0, lPreRowOffset = 0;
/**全屏一格格操作,数据每一格offset 768*/
for (DWORD lPreRow = 0; lPreRow < wCell*hCell; lPreRow++, lPreRowOffset += 768)
{
DWORD iFound = 0;///与原数据对比,发现相同像素点个数
DWORD lPrePoint = lPreRowOffset;
DWORD lInPoint = ((lPreRow%wCell) + (lPreRow/wCell)*w)*48;
for (DWORD row = 0 ; row < 16 ; row ++)
{
/**如果超出当前屏幕则清0*/
if (lInPoint > w*h*3)
{
memset(m_lpPreData + lPrePoint, 0,48);
}
/**没超出就比较是否有不同的点*/
else
{
if (iFound == 0 && bPre)
{
for (int i = 0 ; i < 48; i++)
{
if (*(m_lpPreData + lPrePoint + i) != *(lpInData + lInPoint+i))
{
iFound++;
break;
}
}//end for
}//end if
memcpy(m_lpPreData + lPrePoint, lpInData + lInPoint, 48); //±
}
lPrePoint += 48; //16 * 3;
lInPoint += w * 3;
}//end for
if (iFound == 0 && bPre) continue;
SETBIT(m_lpOutBuffer, lPreRow);
//
memcpy(lpOutData + lOutRowOffset,m_lpPreData + lPreRowOffset, 768); //16*16*3
lOutRowOffset += 768;
}//end for
*lWidth = 16;
*lHeight = lOutRowOffset/(16*3);
*lHeadSize = hSize;
*lSize = lOutRowOffset;
return m_lpOutBuffer;
}


二、将变化部分拼成的图片(bmp),根据变化头还原数据到桌面图片数据中

#define GETBIT(p, x) ((unsigned char)p[x/8] >> (x%8) & 1)
BYTE * FixtoBMP(unsigned char * lpInData,
unsigned long lWidth ,
unsigned long lHeight,
unsigned char * lpHeadData,
unsigned long lHeadSize,
unsigned long w,
unsigned long h)
{
if (w % 16) return NULL;
int hCell = h / 16;
if (hCell % 16){
hCell++;
}
int wCell = w / 16;
int hSize = (wCell*hCell)/8;
if ((wCell*hCell)%8){
hSize++;
}
if (hSize != lHeadSize) return NULL;
DWORD lBufSize = (long)w * 3 * (long)h;
////////////////////////////////////////////////////////////////////////////
if (m_lpPreData==NULL)
{
m_lpPreData = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
if (m_lpPreData == NULL) return NULL;
memset(m_lpPreData,0, lBufSize);
}
DWORD lFullRow, row ;
DWORD lFullRowOffset = 0, lFullPoint = 0;
DWORD lPreRowOffset = 0, lPrePoint;
for (lFullRow = 0; lFullRow < wCell*hCell; lFullRow++)
{
lPrePoint = ((lFullRow%wCell) + (lFullRow/wCell)*w)*48;
if (GETBIT(lpHeadData, lFullRow))//²»Ïàͬ
{
for (row = 0 ; row < 16 ; row ++)
{
if (lPrePoint+1 < lBufSize)
{
memcpy(m_lpPreData + lPrePoint, lpInData + lFullPoint, 48);
}
lPrePoint  += w * 3;
lFullPoint += 48; //16 * 3
}//end for
}//end if
}//end for
return m_lpPreData;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐