背景描述
在視頻監控軟件中,我們看到很多的軟件都有電子放大功能, 按住鼠標左鍵不放,框選一個區域,再松開鼠標左鍵,即對選中的區域進行放大顯示, 且可以重復該操作,逐步放大所需顯示的區域, 有沒有覺得,這個功能在視頻監控軟件中還是有他的用武地. 今天我們就來實現該功能;
實現流程
//設置電子放大起起始點
int SetElectronicZoomStartPoint(int channelId, float fXPercent, float fYPercent, unsigned char showBox);
//設置電子放大結束點(在鼠標移動過程中可一直調用該函數)
int SetElectronicZoomEndPoint(int channelId, float fXPercent, float fYPercent);
//設置是否放大顯示
int SetElectronicZoom(int channelId, int zoomIn);
//復位
void ResetElectronicZoom(int channelId);
//直接設置顯示區域,用於電子放大, 在某些場合, 需要直接進行縮放顯示, 即可調用該函數實現
int SetRenderRect(int channelId, LPRECT lpSrcRect);
代碼實現
int ChannelManager::ElectronicZoomProcess(MEDIA_VIDEO_CHANNEL_OBJ_T *pMediaChannel, EASY_FRAME_INFO *frameInfo)
{
if (NULL == pMediaChannel) return 0;
if (NULL == frameInfo) return 0;
ELECTRONIC_ZOOM_T *pElectoricZoom = pMediaChannel->pElectoricZoom;
if (NULL == pElectoricZoom) return 0;
int nLeft = 0, nTop = 0, nRight = 0, nBottom = 0;
if (pElectoricZoom->zoomIn >= 0x01)
{
RECT rcClient;
GetClientRect(pMediaChannel->mediaDisplay.hWnd, &rcClient);
float fLeftPercent = pElectoricZoom->fStartPointX;
float fTopPercent = pElectoricZoom->fStartPointY;
float fRightPercent = pElectoricZoom->fEndPointX;
float fBottomPercent = pElectoricZoom->fEndPointY;
if (fRightPercent > fLeftPercent && fBottomPercent > fTopPercent) //逐步放大
{
if (pElectoricZoom->fVideoWidth > 0)
{
int video_width = (int)pElectoricZoom->fVideoWidth;
int video_height= (int)pElectoricZoom->fVideoHeight;
nLeft = (int)((float)video_width / 100.0f * fLeftPercent);
nTop = (int)((float)video_height/ 100.0f * fTopPercent);
nRight = (int)((float)video_width / 100.0f * fRightPercent);
nBottom = (int)((float)video_height/ 100.0f * fBottomPercent);
if (nRight > nLeft && nBottom > nTop)
{
pElectoricZoom->fVideoWidth = (float)(nRight - nLeft);
pElectoricZoom->fVideoHeight = (float)(nBottom - nTop);
nLeft = pElectoricZoom->startVideoLeft + nLeft;
nTop = pElectoricZoom->startVideoTop + nTop;
nRight = pElectoricZoom->startVideoLeft + nRight;
nBottom = pElectoricZoom->startVideoTop + nBottom;
pElectoricZoom->startVideoLeft = nLeft;
pElectoricZoom->startVideoTop = nTop;
if (pElectoricZoom->zoomIndex + 1 <MAX_ZOOM_IN_TIMES)
{
SetRect(&pElectoricZoom->zoomParam[pElectoricZoom->zoomIndex].rect, nLeft, nTop, nRight, nBottom);
pElectoricZoom->zoomParam[pElectoricZoom->zoomIndex].fVideoWidth = pElectoricZoom->fVideoWidth;
pElectoricZoom->zoomParam[pElectoricZoom->zoomIndex].fVideoHeight = pElectoricZoom->fVideoHeight;
pElectoricZoom->zoomParam[pElectoricZoom->zoomIndex].startVideoLeft = pElectoricZoom->startVideoLeft;
pElectoricZoom->zoomParam[pElectoricZoom->zoomIndex].startVideoTop = pElectoricZoom->startVideoTop;
pElectoricZoom->zoomIndex ++;
}
}
else
{
int idx = pElectoricZoom->zoomIndex-2;
if (idx > 0)
{
nLeft = pElectoricZoom->zoomParam[idx].rect.left;
nTop = pElectoricZoom->zoomParam[idx].rect.top;
nRight = pElectoricZoom->zoomParam[idx].rect.right;
nBottom = pElectoricZoom->zoomParam[idx].rect.bottom;
pElectoricZoom->fVideoWidth = pElectoricZoom->zoomParam[idx].fVideoWidth;
pElectoricZoom->fVideoHeight = pElectoricZoom->zoomParam[idx].fVideoHeight;
pElectoricZoom->startVideoLeft = pElectoricZoom->zoomParam[idx].startVideoLeft;
pElectoricZoom->startVideoTop = pElectoricZoom->zoomParam[idx].startVideoTop;
}
}
}
else
{
int video_width = frameInfo->width;
int video_height= frameInfo->height;
nLeft = (int)((float)video_width / 100.0f * fLeftPercent);
nTop = (int)((float)video_height/ 100.0f * fTopPercent);
nRight = (int)((float)video_width / 100.0f * fRightPercent);
nBottom = (int)((float)video_height/ 100.0f * fBottomPercent);
pElectoricZoom->startVideoLeft = nLeft;
pElectoricZoom->startVideoTop = nTop;
pElectoricZoom->fVideoWidth = (float)(nRight - nLeft);
pElectoricZoom->fVideoHeight = (float)(nBottom - nTop);
SetRect(&pElectoricZoom->zoomParam[0].rect, nLeft, nTop, nRight, nBottom);
pElectoricZoom->zoomParam[0].fVideoWidth = pElectoricZoom->fVideoWidth;
pElectoricZoom->zoomParam[0].fVideoHeight = pElectoricZoom->fVideoHeight;
pElectoricZoom->zoomParam[0].startVideoLeft = pElectoricZoom->startVideoLeft;
pElectoricZoom->zoomParam[0].startVideoTop = pElectoricZoom->startVideoTop;
pElectoricZoom->zoomIndex ++;
}
}
else
{
if (pElectoricZoom->zoomIndex > 1)
{
int idx = pElectoricZoom->zoomIndex-2;
nLeft = pElectoricZoom->zoomParam[idx].rect.left;
nTop = pElectoricZoom->zoomParam[idx].rect.top;
nRight = pElectoricZoom->zoomParam[idx].rect.right;
nBottom = pElectoricZoom->zoomParam[idx].rect.bottom;
pElectoricZoom->fVideoWidth = pElectoricZoom->zoomParam[idx].fVideoWidth;
pElectoricZoom->fVideoHeight = pElectoricZoom->zoomParam[idx].fVideoHeight;
pElectoricZoom->startVideoLeft = pElectoricZoom->zoomParam[idx].startVideoLeft;
pElectoricZoom->startVideoTop = pElectoricZoom->zoomParam[idx].startVideoTop;
pElectoricZoom->zoomIndex --;
}
else
{
pElectoricZoom->fVideoWidth = 0.0f;
nLeft = 0;
nTop = 0;
nRight = frameInfo->width;
nBottom = frameInfo->height;
pElectoricZoom->zoomIndex = 0;
}
}
RECT rcSrc;
SetRect(&rcSrc, nLeft, nTop, nRight, nBottom);
CopyRect(&pMediaChannel->mediaDisplay.rcSrcRender, &rcSrc);
pElectoricZoom->zoomIn --;
}
return 0;
}
關於EasyPlayerPro
EasyPlayerPro是一款全功能的流媒體播放器,支持RTSP、RTMP、HTTP、HLS、UDP、RTP、File等多種流媒體協議播放、支持本地文件播放,支持本地抓拍、本地錄像、播放旋轉、多屏播放、倍數播放等多種功能特性,核心基於ffmpeg,穩定、高效、可靠、可控,支持Windows、Android、iOS三個平台,目前在多家教育、安防、行業型公司,都得到的應用,廣受好評!
EasyPlayerPro:https://github.com/EasyDSS/EasyPlayerPro
點擊鏈接加入群【EasyPlayer & EasyPlayerPro】:544917793
技術支持
-
QQ交流群:544917793
EasyPlayerPro是一款非常穩定的全協議/全功能播放器組件,各平台版本需要經過授權才能商業使用,商業授權方案可以通過以上渠道進行更深入的技術與合作咨詢;
獲取更多信息
EasyDarwin開源流媒體服務器:www.EasyDarwin.org
EasyDSS商用流媒體解決方案:www.EasyDSS.com
EasyNVR無插件直播方案:www.EasyNVR.com
Copyright © EasyDarwin Team 2012-2017