背景描述

在视频监控软件中,我们看到很多的软件都有电子放大功能, 按住鼠标左键不放,框选一个区域,再松开鼠标左键,即对选中的区域进行放大显示, 且可以重复该操作,逐步放大所需显示的区域, 有没有觉得,这个功能在视频监控软件中还是有他的用武地. 今天我们就来实现该功能;

实现流程

//设置电子放大起起始点
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

技术支持

EasyPlayerPro是一款非常稳定的全协议/全功能播放器组件,各平台版本需要经过授权才能商业使用,商业授权方案可以通过以上渠道进行更深入的技术与合作咨询;

获取更多信息

EasyDarwin开源流媒体服务器:www.EasyDarwin.org

EasyDSS商用流媒体解决方案:www.EasyDSS.com

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

Copyright © EasyDarwin Team 2012-2017

EasyPlayerPro Windows播放器电子放大/局部放大播放功能实现的更多相关文章

  1. EasyPlayerPro windows播放器本地音频播放音量控制实现

    背景描述 作为一个播放器, 除了能播放视频和声音外,音量控制是绝对不能缺少的功能; 本文在音视频播放的基础上,增加对音量的控制: 实现流程 调用mixerGetDevCaps获取音频输出设备列表; 打 ...

  2. EasyPlayerPro Windows播放器进行本地对讲喊话音频采集功能实现

    需求 在安防行业应用中,除了在本地看到摄像机的视频和进行音频监听外,还有一个重要的功能,那就是对讲. EasyPlayerPro-win为了减轻二次开发者的工作量,将本地音频采集也进行了集成: 功能特 ...

  3. EasyPlayerPro windows播放器在播放RTMP视频显示重复异常问题解决

    问题来源 2017.12.18 今日有杭州某教育领域客户反馈EasyPlayerPro在播放一个rtmp源时,画面显示异常的问题.截图如下: 问题复现 一番思考, 将显示格式改为D3D显示, 正常, ...

  4. EasyPlayerPro windows播放器本地配置文件配置方法介绍

    需求背景 应EasyPlayerPro某客户需求,在EasyPlayerPro启动时,自动播放指定的url源, 不需要每次都去手动填写, 且实现自动播放,不需要手动的单击播放按钮: 为响应该需求,特增 ...

  5. EasyPlayerPro Windows播放器读取xml配置文件中的特殊字符问题

    问题被反馈 今日一客户反馈说播放不了带用户名密码的流, 奇怪,这个问题不存在啊-,按照客户的说法, 是将url地址保存在配置文件中,然后再打开EasyPlayerPro运行: 问题复现 在EasyPl ...

  6. EasyPlayerPro Windows播放器本地快照抓拍截图功能实现方法

    背景描述 作为一个播放器,截图功能必不可少; 下面主要记录一下截图功能的实现: 实现流程 将解码后的帧进行格式转换(目标格式为RGB24); 采用独立的线程进行截图处理; 截图可保存为BMP或JPG两 ...

  7. EasyPlayerPro Windows播放器全屏模式下GDI显示出现黑屏问题解决

    问题来源 2017.12.21 前天有杭州某教育领域客户反馈有部分视频源在全屏模式下显示黑屏: 问题复现 EasyPlayerPro由于没有实现单个窗口完全全屏,故没有暴露该问题,晚上加班,加上单个窗 ...

  8. EasyPlayerPro Windows播放器实时流进行本地缓冲区即时回放功能实现

    背景描述 参照国内视频监控行业监控软件,实现当前视频的即时回放功能,例如: 监控人员发现刚刚的某个视频点有可疑,就像录像回放一样,想倒回去看一下,但又不想切换到录像回放界面, 此处就体现即时回放的价值 ...

  9. EasyPlayer RTSP Windows播放器D3D,GDI的几种渲染方式的选择区别

    EasyPlayer-RTSP windows播放器支持D3D和GDI两种渲染方式,其中D3D支持格式如下: DISPLAY_FORMAT_YV12 DISPLAY_FORMAT_YUY2 DISPL ...

随机推荐

  1. AC日记——食物链 codevs 1047

    1074 食物链 2001年NOI全国竞赛  时间限制: 3 s  空间限制: 64000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 动物王国中有 ...

  2. Codeforces Round #450 (Div. 2) C. Remove Extra One【*模拟链表/一个数比前面所有数大就是个record。删掉一个数,让record的个数尽量多。】

    C. Remove Extra One time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. mysql控制台入门级--简单的创建表,字段。。。(用于网站测试)

    一:在Mysql控制台创建数据表 [sql]  use ceshi;  create table student  (      stuid int primary key auto_incremen ...

  4. GCJ——Crazy Rows (2009 Round 2 A)

    题意: 给定一个N*N的矩阵,由0,1组成,只允许交换相邻的两行,把矩阵转化为下三角矩阵(对角线上方全是0),最少需要多少次交换?(保证可以转化为下三角矩阵) Large: N<=40 解析: ...

  5. spring-cloud - 服务之间的通信

    上文中已经讲述了基本环境搭建,本文基于上文环境https://www.cnblogs.com/xxpandong/p/10485172.html. spring-cloud中微服务之间通信主要有俩种形 ...

  6. Docker 创建image

      images 是containers的基础.每次使用docker run 命令都要指定image.   列出本地images   zane@zane-V:~$ docker images REPO ...

  7. Unity -- 使用easyAR的基础教程

    “三人行,必有我师焉”,抱着共同学习进步的态度,和大家一起交流下EasyAR的用法.有不足的地方,欢迎指出!大家都知道,今年的QQ,支付宝,都用到了AR的技术,扫描一张图片,就会出现虚拟模型,及其想要 ...

  8. 前台页面获取servlet传过来的数据

    servlet中的代码: public void doGet(HttpServletRequest request, HttpServletResponse response) throws Serv ...

  9. dedecms 调用父栏目下的所有子栏目

    效果如下: 代码如下: <div class="productxilie"> <ul> {dede:channelartlist row=6 typeid ...

  10. 原生JavaScript技巧大收集100个

    原生JavaScript技巧大收集 1.原生JavaScript实现字符串长度截取function cutstr(str, len) { var temp; var icount = 0; var p ...