再次研究videocapX视频摄像头控件
上次想要调用这个控件来显示视频,当时失败了.就放弃了
10.1出去玩了一圈之后,突然觉得应该再研究一下,感觉思路清晰了,应该可以成功.
下面记录下自己一点一点是怎么想的和实现的过程, 给自己一个研究下去的动力.
首先,去百度上搜了破解版(这个是收费控件), 里面包含了一个破解的软件
1, 注册了原来文件夹里的videocapX.ocx .
2,点开自带的示例app ,发现提示试用30已经过期...必须注册....
3,双击破解软件,破解完成后, 重新注册了破解之后的这个控件,
4,再次点开示例的app发现不提示了,而且也打开了视频设置界面, 勾选里面的time显示在视频那个选项之后,视频可以很好的显示了.
这样就可以开始用aardio调用ocx了.
下面的试验我上传到了网盘里:
链接:https://pan.baidu.com/s/1tbfK9ZUnK58cRLCETrhxQA
提取码:nb1s
解决了.
群里大神提供了个测试代码, 在需要设置的属性名前面加上set关键词
import win.ui; /*DSG{{*/ mainForm = win.form(text="aardio form";right=759;bottom=469) mainForm.add() /*}}*/ mainForm.enableDpiScaling(); mainForm.show(); import console var VideoCapX1 = mainForm.createEmbed("{912FB007-DD9A-11D3-BD8D-DAAFCB8D9378}") var cap = VideoCapX1._object cap.GetVideoDeviceCount() cap.GetVideoDeviceName(0) cap.setVideoDeviceIndex(0) cap.setPreviewScale(true) cap.setConnected(true) console.varDump(cap.GetVideoCaps()[1]) cap.setPreview(true) return win.loopMessage();
我猜测:
今天测试sv4000这个摄像头,翻转是可以使用的.
下面是四通道显示
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=897;bottom=675) winform.add( button={cls="button";text="about";left=5;top=626;right=164;bottom=668;z=1}; button2={cls="button";text="audio";left=179;top=626;right=276;bottom=668;z=2}; button3={cls="button";text="vedio";left=287;top=626;right=384;bottom=668;z=3}; button4={cls="button";text="version";left=783;top=623;right=880;bottom=665;z=4}; button5={cls="button";text="flip";left=411;top=626;right=508;bottom=668;z=6}; button6={cls="button";text="show";left=782;top=509;right=879;bottom=551;z=7}; button7={cls="button";text="show";left=783;top=559;right=880;bottom=601;z=8}; custom1={cls="custom";text="自定义控件";left=0;top=0;right=299;bottom=256;z=5}; custom2={cls="custom";text="自定义控件";left=343;top=0;right=642;bottom=256;z=9}; custom3={cls="custom";text="自定义控件";left=7;top=307;right=306;bottom=563;z=10}; custom4={cls="custom";text="自定义控件";left=343;top=310;right=642;bottom=566;z=11} ) /*}}*/ import console console.open() var cvx = {}; for(i=1;4;1){ cvx[i] = winform["custom"++i].createEmbed("{912FB007-DD9A-11D3-BD8D-DAAFCB8D9378}"); } winform.button.oncommand = function(id,event){ cvx[1]._object.AboutBox() } winform.button2.oncommand = function(id,event){ console.log("音频数量:", cvx[1]._object.GetAudioDeviceCount() ) for(i=0;cvx[1]._object.GetAudioDeviceCount()-1;1){ console.log( cvx[1]._object.GetAudioDeviceName(i) ) } } winform.button3.oncommand = function(id,event){ console.log("摄像头数量:", cvx[1]._object.GetVideoDeviceCount() ) for(i=0;cvx[1]._object.GetVideoDeviceCount()-1;1){ console.log( cvx[1]._object.GetVideoDeviceName(i) ) } for(i=1;4;1){ cvx[i]._object.setVideoDeviceIndex(i-1); cvx[i]._object.setPreviewScale(true) cvx[i]._object.setConnected(true); cvx[i]._object.setPreview(true); } } winform.button4.oncommand = function(id,event){ console.log( cvx[1]._object.getVideoFlip() ) } winform.button5.oncommand = function(id,event){ console.log( cvx[1]._object.setVideoFlip(-3) ); } winform.button6.oncommand = function(id,event){ cvx[1]._object.ShowVideoSourceDlg(); } winform.button7.oncommand = function(id,event){ cvx[1]._object.ShowVideoFormatDlg() } winform.show() win.loopMessage();
给视频控件加个蒙版: 实现蒙版上面画线 (给视频画线)
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=491;bottom=483;bgcolor=16777215) winform.add( button={cls="button";text="Button";left=283;top=368;right=473;bottom=447;z=3}; picturebox={cls="picturebox";left=57;top=69;right=380;bottom=318;bgcolor=15780518;db=1;dl=1;dr=1;dt=1;z=2}; plus={cls="plus";left=57;top=69;right=380;bottom=318;bgcolor=255;db=1;dl=1;dr=1;dt=1;notify=1;transparent=1;z=1} ) /*}}*/ var VideoCapX1 = winform.picturebox.createEmbed("{912FB007-DD9A-11D3-BD8D-DAAFCB8D9378}") var cap = VideoCapX1._object cap.GetVideoDeviceCount() cap.GetVideoDeviceName(0) cap.setVideoDeviceIndex(0) cap.setPreviewAudio(0); cap.setPreviewScale(true) cap.setConnected(true) cap.setPreview(true) //自绘plus背景 winform.plus.onDrawBackground = function(graphics,rc,backgroundColor,clr){ var pen = gdip.pen(backgroundColor,2); graphics.drawLine(pen,(rc.right-rc.left)/2,rc.top,(rc.right-rc.left)/2,rc.bottom); pen.delete() return true;//返回true阻止绘制默认背景 } winform.plus.orphanWindow(true); winform.show() win.loopMessage();
根据鼠标点击位置动态画线:
这里注意: 由于picturebox被videocapx使用了,鼠标左键单击信息貌似被屏蔽了,拦截不到, 但是下面的消息可以使用.
var xx,yy; mainForm.picturebox.wndproc = function(hwnd,message,wParam,lParam){ select(message) { case 0x210/*_WM_PARENTNOTIFY*/ { xx,yy = win.getMessagePos(lParam); //通知plus重画 mainForm.plus.redraw() } else { } } } //自绘plus背景 mainForm.plus.onDrawBackground = function(graphics,rc,backgroundColor,clr){ var pen = gdip.pen(backgroundColor,2); if(xx){ graphics.drawLine(pen,xx,rc.top,xx,rc.bottom); }else { graphics.drawLine(pen,(rc.right-rc.left)/2,rc.top,(rc.right-rc.left)/2,rc.bottom); } pen.delete() return true;//返回true阻止绘制默认背景 } mainForm.plus.orphanWindow(true);
画多重线方法:
var mtab = {}; var xx,yy; mainForm.picturebox.wndproc = function(hwnd,message,wParam,lParam){ select(message) { case 0x210 { xx,yy = win.getMessagePos(lParam) table.push(mtab,{xx;yy}) if(#mtab >1){ table.shift(mtab,1); } mainForm.plus.redraw() } else { } } } //自绘plus背景 mainForm.plus.onDrawBackground = function(graphics,rc,backgroundColor,clr){ var pen = gdip.pen(backgroundColor,1); if(mtab){ for(i=1;#mtab;1){ graphics.drawLine(pen,mtab[i][1],mtab[i][2],rc.right,mtab[i][2]+(rc.width()-mtab[i][1])*math.tan(math.rad(18))); graphics.drawLine(pen,mtab[i][1],mtab[i][2],rc.left,mtab[i][2]-mtab[i][1]*math.tan(math.rad(18))); graphics.drawLine(pen,rc.left,mtab[i][2],rc.right,mtab[i][2]); } } pen.delete() return true;//返回true阻止绘制默认背景 } mainForm.plus.orphanWindow(true);
鼠标点击画十字可调整角度线:
画板端代码:
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=740;bottom=684) winform.add( picturebox={cls="picturebox";left=0;top=0;right=741;bottom=685;db=1;dl=1;dr=1;dt=1;z=1}; plus={cls="plus";left=0;top=0;right=741;bottom=685;bgcolor=255;db=1;dl=1;dr=1;dt=1;z=2} ) /*}}*/ arg={...}; parent = table.shift(arg); var mtab = {}; var xx,yy; try{ var cvx = winform.picturebox.createEmbed("{912FB007-DD9A-11D3-BD8D-DAAFCB8D9378}"); cvx._object.setVideoDeviceIndex(arg[1].index); cvx._object.setPreviewScale(true) cvx._object.setPreviewAudio(0); cvx._object.setConnected(true); cvx._object.setPreview(true); cvx._object.setVideoFlip(arg[1].flip); winform.text = arg[1].title; } catch(e){ winform.msgboxErr("摄像头打开失败") } winform.picturebox.wndproc = function(hwnd,message,wParam,lParam){ if(arg[1].Lineopen){ select(message) { case 0x210 { xx,yy = win.getMessagePos(lParam) table.push(mtab,{xx;yy}) if(#mtab >1){ table.shift(mtab,1); } winform.plus.redraw() } else { } } } } //自绘plus背景 winform.plus.onDrawBackground = function(graphics,rc,backgroundColor,clr){ if(arg[1].Lineopen){ var pen = gdip.pen(backgroundColor,arg[1].lineWidth); if(mtab){ for(i=1;#mtab;1){ if((arg[1].angle == "90") or (arg[1].angle=="270")){ graphics.drawLine(pen,mtab[i][1],rc.top,mtab[i][1],rc.bottom); graphics.drawLine(pen,rc.left,mtab[i][2],rc.right,mtab[i][2]); }else { graphics.drawLine(pen,mtab[i][1],mtab[i][2],rc.right,mtab[i][2]+(rc.width()-mtab[i][1])*math.tan(math.rad(arg[1].angle))); graphics.drawLine(pen,mtab[i][1],mtab[i][2],rc.left,mtab[i][2]-mtab[i][1]*math.tan(math.rad(arg[1].angle))); graphics.drawLine(pen,rc.left,mtab[i][2],rc.right,mtab[i][2]); } } } pen.delete() } return true;//返回true阻止绘制默认背景 } winform.plus.orphanWindow(true); winform.show(); win.loopMessage(); return winform;
主界面端代码:
import win.ui; /*DSG{{*/ mainForm = win.form(text="摄像头V2";right=385;bottom=147) mainForm.add( button={cls="button";text="开启";left=255;top=23;right=371;bottom=97;z=1}; checkbox={cls="checkbox";text="开启画线";left=26;top=117;right=110;bottom=135;z=4}; edit={cls="edit";text="18";left=174;top=117;right=232;bottom=141;align="center";border=1;num=1;z=5}; flip={cls="combobox";left=24;top=71;right=232;bottom=97;edge=1;items={"不翻转";"上下翻转";"左右镜像";"全镜像"};mode="dropdown";z=3}; static={cls="static";text="画线角度:";left=109;top=116;right=167;bottom=140;align="right";center=1;transparent=1;z=6}; sxtlist={cls="combobox";left=26;top=23;right=232;bottom=49;edge=1;items={};mode="dropdown";z=2}; trackbar={cls="trackbar";left=248;top=107;right=371;bottom=137;max=8;min=1;z=7} ) /*}}*/ import com.activeX; if(!io.exist("\res\videocapx.lic")){ string.save("\res\videocapx.lic",$"\res\videocapx.lic"); } if(!io.exist("\res\videocapx.ocx")){ string.save("\res\videocapx.ocx",$"\res\videocapx.ocx"); } com.activeX.regsvr32As("\res\videocapx.ocx") var sxtobj = com.CreateObject("{912FB007-DD9A-11D3-BD8D-DAAFCB8D9378}") for(i=0;sxtobj.GetVideoDeviceCount()-1;1){ mainForm.sxtlist.add(sxtobj.GetVideoDeviceName(i)) } mainForm.sxtlist.selIndex = 1; //mainForm.trackbar.pos = 1; mainForm.button.oncommand = function(id,event){ var flipmode; select(mainForm.flip.text) { case "不翻转" { flipmode = 0; } case "上下翻转" { flipmode = -2; } case "左右镜像" { flipmode = -1; } case "全镜像" { flipmode = -3; } else { } } var frmChild = mainForm.loadForm("\dlg\sxt.aardio",{index=mainForm.sxtlist.selIndex-1;flip=flipmode;title=mainForm.sxtlist.text;Lineopen=mainForm.checkbox.checked;angle=mainForm.edit.text;lineWidth=mainForm.trackbar.pos}); frmChild.show(); } mainForm.show(); return win.loopMessage();
摄像头上显示按键和图像:
不用.orphanWindow(true)方式
其实就类似于两个控件重叠了, 两个控件又都有自己的事件, 那么要显示另外一个控件的事件,就需要指定父窗体, 然后就可以自动调用事件了.
在aardio里创建工程选项里有一个[高级界面]->里面的[播放器] 那个里面其实就用到了这个,
可以看到右上角又个搜索框, 搜索框里又有个button这样的搜索图标, 这个图标可以点击进行搜索
那么要想点击这个图标, 就需要指定这个搜索图标的父窗体为下面的那个控件
于是:
随便拖拉一个plus, 设置好按钮的点击样式, 什么都不要做, 然后设置,这个plus的parent为picturebox即可.
import fonts.fontAwesome; import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=812;bottom=577;bgcolor=16777215) winform.add( picturebox={cls="picturebox";left=22;top=23;right=710;bottom=374;bgcolor=15780518;db=1;dl=1;dr=1;dt=1;z=1}; plus={cls="plus";left=370;top=305;right=527;bottom=362;bgcolor=65280;z=3}; plus2={cls="plus";text="预览按钮效果";left=559;top=308;right=701;bottom=363;bgcolor=-8355840;font=LOGFONT(h=-16;name='FontAwesome';charset=0);notify=1;z=2}; plus3={cls="plus";left=272;top=5;right=278;bottom=474;bgcolor=255;z=4} ) /*}}*/ winform.plus2.skin({ background={ active=0xFFCF8E2D; default=0xFF008080; hover=0xFF00C2C2 }; }) winform.plus.skin({ background={ active=0xFFCF8E2D; default=0xFF008080; hover=0xFF00C2C2 }; }) var VideoCapX1 = winform.picturebox.createEmbed("{912FB007-DD9A-11D3-BD8D-DAAFCB8D9378}") var cap = VideoCapX1._object cap.GetVideoDeviceCount() cap.GetVideoDeviceName(0) cap.setVideoDeviceIndex(0) cap.setPreviewAudio(0); cap.setPreviewScale(true) cap.setConnected(true) cap.setPreview(true) //自绘plus背景 /* winform.plus3.onDrawBackground = function(graphics,rc,backgroundColor,clr){ var pen = gdip.pen(backgroundColor,2); graphics.drawLine(pen,(rc.right-rc.left)/2,rc.top,(rc.right-rc.left)/2,rc.bottom); pen.delete() return true;//返回true阻止绘制默认背景 } */ winform.plus2.oncommand = function(id,event){ winform.msgbox("点击了") } winform.plus3.setParent(winform.picturebox) winform.plus2.setParent(winform.picturebox) winform.plus.setParent(winform.picturebox) winform.show() win.loopMessage();
实现: 鼠标移动到摄像头区域 按钮 显示, 移出就隐藏功能
import win.ui; /*DSG{{*/ mainForm = win.form(text="aardio工程37";right=959;bottom=591) mainForm.add( picturebox={cls="picturebox";left=94;top=38;right=854;bottom=508;bgcolor=12632256;db=1;dl=1;dr=1;dt=1;z=1}; plus={cls="plus";left=378;top=367;right=535;bottom=424;bgcolor=65280;db=1;dl=1;dr=1;z=3}; plus2={cls="plus";text="预览按钮效果";left=567;top=370;right=709;bottom=425;bgcolor=-8355840;db=1;dr=1;font=LOGFONT(h=-16;name='FontAwesome';charset=0);hide=1;notify=1;z=2} ) /*}}*/ mainForm.plus2.skin({ background={ active=0xFFCF8E2D; default=0xFF008080; hover=0xFF00C2C2 }; }) mainForm.plus.skin({ background={ active=0xFFCF8E2D; default=0xFF008080; hover=0xFF00C2C2 }; }) var VideoCapX1 = mainForm.picturebox.createEmbed("{912FB007-DD9A-11D3-BD8D-DAAFCB8D9378}") var cap = VideoCapX1._object cap.GetVideoDeviceCount() cap.GetVideoDeviceName(0) cap.setVideoDeviceIndex(0) cap.setPreviewAudio(0); cap.setPreviewScale(true) cap.setConnected(true) cap.setPreview(true) mainForm.plus2.oncommand = function(id,event){ mainForm.msgbox("哈哈哈") } //显示按钮在摄像头之上 mainForm.plus2.setParent(mainForm.picturebox) mainForm.plus.setParent(mainForm.picturebox) mainForm.show(); //必须加载鼠标事件库 import mouse; return win.loopMessage( //消息循环里判断鼠标位置 function(){ var x,y = mouse.getPos() if( ::PtInRect(mainForm.picturebox.getRect(true),x,y) ) mainForm.plus2.hide = false; else { mainForm.plus2.hide = true; } } );
写在消息循环里不知道会不会影响界面刷新效率?
更新:
增加鼠标右键点击才能显示按钮, 移出摄像头就消失功能
mainForm.picturebox.wndproc = function(hwnd,message,wParam,lParam){ console.log(hwnd,message,wParam,lParam) if(message == 123){ var x,y = win.getMessagePos(lParam) var xx,yy = win.toClient(mainForm.picturebox.hwnd,x,y) mainForm.plus2.setPos(xx,yy); mainForm.plus2.hide = false; } //无返回值则继续调用默认回调函数 } import mouse; return win.loopMessage( //消息循环里判断鼠标位置 function(){ var x,y = mouse.getPos(); if( !::PtInRect(mainForm.picturebox.getRect(true),x,y) ) { mainForm.plus2.hide = true; } } );
登录后方可回帖
对了,首先记录一下,怎么去查看com控件(ocx和dll)的GUID码的:
我这里利用了一个名字为ComRaider的工具, 使用方法很简单百度下即可.
言归正传↓
我的原则是先测试功能,再封装为库, 所以:
首先创建了一个winform窗口
然后调用控件的aboutbox()属性
可以看到运行后得到了想要的东西.