EasyPlayerPro Windows播放器電子放大/局部放大播放功能實現


背景描述

在視頻監控軟件中,我們看到很多的軟件都有電子放大功能, 按住鼠標左鍵不放,框選一個區域,再松開鼠標左鍵,即對選中的區域進行放大顯示, 且可以重復該操作,逐步放大所需顯示的區域, 有沒有覺得,這個功能在視頻監控軟件中還是有他的用武地. 今天我們就來實現該功能;

EasyPlayerPro

實現流程

//設置電子放大起起始點
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);

EasyPlayerPro

代碼實現

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

技術支持

EasyPlayerPro是一款非常穩定的全協議/全功能播放器組件,各平台版本需要經過授權才能商業使用,商業授權方案可以通過以上渠道進行更深入的技術與合作咨詢;

獲取更多信息

EasyDarwin開源流媒體服務器:www.EasyDarwin.org

EasyDSS商用流媒體解決方案:www.EasyDSS.com

EasyNVR無插件直播方案:www.EasyNVR.com

Copyright © EasyDarwin Team 2012-2017

EasyDarwin


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM