怎么我用这一个函数会出现乱码?是海康压缩卡的SDK[ds40xxsdk.dll]
官方的SDK是
=========================================================================
4.42 SetOsdDisplayMode(HANDLE hChannelHandle, int Brightness, BOOL Translucent, int TwinkleInterval, USHORT *Format1, USHORT *Format2)
参数:HANDLE hChannelHandle 通道句柄
int Brightness OSD显示亮度,255最亮,0最暗;
BOOL Translucent OSD图象是否做半透明处理;
Int TwinkleInterval (V3.2改动为:当值为1时,OSD的亮度根据背景的亮度来调整,但背景较亮时,OSD亮度自动调低,但背景较暗时,OSD亮度自动调亮。原来的闪烁功能关闭)3.2版本之前请参考4.41节描述。
USHORT *Forma1,* Format2 描述字符叠加的位置和次序的格式
串,具体定义如下:
USHORT X, USHORT Y, CHAR0, CHAR1, CHAR2,… CHARN, NULL
其中X,Y 是该字串在标准CIF图象的起始位置,X必须是8的倍数,Y可以在图象高度内取值即(0-287)PAL 、(0-239)NTSC;CHARN也是USHORT型的参数,可以是ASCII码也可以是汉字,当想要显示当前时间时,可以指定为固定的时间定义值,其值如下:
_OSD_YEAR4 四位的年显示,如2002
_OSD_YEAR2 两位的年显示,如02
_OSD_MONTH3 英文的月显示,如 Jan
_OSD_MONTH2 两位阿拉伯数字的月显示,如07
_OSD_DAY 两位的阿拉伯数字的日显示,如31
_OSD_WEEK3 英文的星期显示,如Tue
_OSD_CWEEK1 中文的星期显示,如星期二
_OSD_HOUR24 24小时的时钟显示,如18
_OSD_HOUR12 12小时的时钟显示,如AM09或PM09
_OSD_MINUTE 两位分钟的显示
_OSD_SECOND 两位秒的显示
在格式字符串的最后必须以NULL(0)结尾,否则会显示错误的内容。
字符串和时间显示可以在FORMAT1 也可以在FORAMT2,也可以混合在一起,但不得超过一行CIF 图象的宽度。
要显示位置在16,19的字符串“办公室”的格式字符串如下:
USHORT Format[] = {16, 19, ‘办’,’公’,’室’, ‘\0’};
要显示位置在8, 3的时间字符串可以如下:
USHORT Format[]={8, 3, _OSD_YEAR4, ‘年’,_OSD_MONTH2,’月’,_OSD_DAY, ‘日’,_OSD_HOUR24,’:’, _OSD_MINUTE, ‘:’, _OSD_SECOND, ‘\0’};
DS-400xH 系列 SDK 说明书 13
海康威视技术文档(版权所有)
如果只想显示其中一行,则将起始的字符串定义如下:
USHORT FormatNoDisplay[]={0, 0, ‘\0’};
==========================================================================================
下面是我调用的
引用:
==========================================================================================
function SetOsdDisplayMode(hChannelHandle:integer;Brightness:integer;Translucent:bool;param:integer;Format1,format2:pointer):integer;stdcall;
==========================================================================================
var
Format1,Format2:array[0..40] of Word ;
_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:word;
begin
Format1[0]:=0;
Format1[1]:=0;
Format1[2]:= Ord(' ') ;
Format1[3]:= _OSD_YEAR4;
Format1[4]:= Ord('-') ;
Format1[5]:= _OSD_MONTH2;
Format1[6]:= Ord('-') ;
Format1[7]:= _OSD_DAY;
Format1[8]:= Ord(#0) ; Format2[0]:= Ord(#0) ;
SetOsdDisplayMode(0,255, false,1, @Format1, @Format2);
setosd(0,true); //这个是启动的
end;
==========================================================================================
官方的SDK是
=========================================================================
4.42 SetOsdDisplayMode(HANDLE hChannelHandle, int Brightness, BOOL Translucent, int TwinkleInterval, USHORT *Format1, USHORT *Format2)
参数:HANDLE hChannelHandle 通道句柄
int Brightness OSD显示亮度,255最亮,0最暗;
BOOL Translucent OSD图象是否做半透明处理;
Int TwinkleInterval (V3.2改动为:当值为1时,OSD的亮度根据背景的亮度来调整,但背景较亮时,OSD亮度自动调低,但背景较暗时,OSD亮度自动调亮。原来的闪烁功能关闭)3.2版本之前请参考4.41节描述。
USHORT *Forma1,* Format2 描述字符叠加的位置和次序的格式
串,具体定义如下:
USHORT X, USHORT Y, CHAR0, CHAR1, CHAR2,… CHARN, NULL
其中X,Y 是该字串在标准CIF图象的起始位置,X必须是8的倍数,Y可以在图象高度内取值即(0-287)PAL 、(0-239)NTSC;CHARN也是USHORT型的参数,可以是ASCII码也可以是汉字,当想要显示当前时间时,可以指定为固定的时间定义值,其值如下:
_OSD_YEAR4 四位的年显示,如2002
_OSD_YEAR2 两位的年显示,如02
_OSD_MONTH3 英文的月显示,如 Jan
_OSD_MONTH2 两位阿拉伯数字的月显示,如07
_OSD_DAY 两位的阿拉伯数字的日显示,如31
_OSD_WEEK3 英文的星期显示,如Tue
_OSD_CWEEK1 中文的星期显示,如星期二
_OSD_HOUR24 24小时的时钟显示,如18
_OSD_HOUR12 12小时的时钟显示,如AM09或PM09
_OSD_MINUTE 两位分钟的显示
_OSD_SECOND 两位秒的显示
在格式字符串的最后必须以NULL(0)结尾,否则会显示错误的内容。
字符串和时间显示可以在FORMAT1 也可以在FORAMT2,也可以混合在一起,但不得超过一行CIF 图象的宽度。
要显示位置在16,19的字符串“办公室”的格式字符串如下:
USHORT Format[] = {16, 19, ‘办’,’公’,’室’, ‘\0’};
要显示位置在8, 3的时间字符串可以如下:
USHORT Format[]={8, 3, _OSD_YEAR4, ‘年’,_OSD_MONTH2,’月’,_OSD_DAY, ‘日’,_OSD_HOUR24,’:’, _OSD_MINUTE, ‘:’, _OSD_SECOND, ‘\0’};
DS-400xH 系列 SDK 说明书 13
海康威视技术文档(版权所有)
如果只想显示其中一行,则将起始的字符串定义如下:
USHORT FormatNoDisplay[]={0, 0, ‘\0’};
==========================================================================================
下面是我调用的
引用:
==========================================================================================
function SetOsdDisplayMode(hChannelHandle:integer;Brightness:integer;Translucent:bool;param:integer;Format1,format2:pointer):integer;stdcall;
==========================================================================================
var
Format1,Format2:array[0..40] of Word ;
_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:word;
begin
Format1[0]:=0;
Format1[1]:=0;
Format1[2]:= Ord(' ') ;
Format1[3]:= _OSD_YEAR4;
Format1[4]:= Ord('-') ;
Format1[5]:= _OSD_MONTH2;
Format1[6]:= Ord('-') ;
Format1[7]:= _OSD_DAY;
Format1[8]:= Ord(#0) ; Format2[0]:= Ord(#0) ;
SetOsdDisplayMode(0,255, false,1, @Format1, @Format2);
setosd(0,true); //这个是启动的
end;
==========================================================================================
是一启动这一个函数的时候就显示乱码,是不是接口有调用问题
Format1, Format2 表示数组的首地址;
看下给你的文档里的这个函数说明
Format1[8]:= Ord(#0) ;
Format1[9]:= #0 ;
Format2[0]:= Ord(#0) ;
Format2[1]:= #0 ;
Format1,Format2:array[0..40] of Word ;
_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:word;
begin
Format1[0]:=0;
Format1[1]:=0;
Format1[2]:= Ord(' ') ;
Format1[3]:= _OSD_YEAR4;
Format1[4]:= Ord('-') ;
Format1[5]:= _OSD_MONTH2;
Format1[6]:= Ord('-') ;
Format1[7]:= _OSD_DAY;
Format1[8]:= ord('\');
Format1[9]:= Ord('0') ; Format2[0]:= Ord('\');
Format2[1]:= Ord('0');
SetOsdDisplayMode(0,255, false,1, @Format1, @Format2);
setosd(0,true); //这个是启动的
end;
2、關于ushort,從說明看這是c#中的類型,16位,兩個字節。由于dot net的類型為對象,值可以是字符串。
3、你在delphi中,應該自己定義兩個字節的char類型,以符合要求
format1,format: array [0..40] of string[2];
Format1[1]:=0;
Format1[2]:= Ord('A') ;
Format1[3]:= Ord('B') ;
Format1[4]:= Ord('C') ;
Format1[5]:= Ord(#0) ; 像这样定义可以正常输出,但是一加_OSD_YEAR4就输出乱码了
另外,对Format参数换种声明可以变成这样,使用方便些:
TMyFormat = packed record
case X: Word of
1 : ( Y: Word; );
2 : ( _: Byte; Text : string[255]);
end;
procedure SetOsdDisplayMode(hChannelHandle: THanlde; Brightness: Integer; Translucent: Boolean; TwinkleInterval: Integer; const Format1, Format2: TMyFormat); //stdcall?;
整个record的长度是259,用的时候最好先清0,然后先写Text,最后写y,比如
var
foo1, foo2 : TMyFormat;
begin
...
FillChar(foo2, SizeOf(foo2), 0);
foo2.Text := Format(' %d-%.2d-%.2d', [year, month, day]);
foo2.X := 0;
foo2.Y := 0;
SetOsdDisplayMode(..., foo1, foo2);
end;
原因是delphi的ShortString的第0个byte用来描述字符串长度,如果先给y赋值再写Text的话,会改变y的高位,定位就不对了
Format1,Format2:array[0..40] of string[2];
begin
Format1[1]:='0';
Format1[2]:= '\0'; Format2[0]:='16';
Format2[1]:='16';
Format2[2]:= 'A';
Format2[3]:= 'A';
Format2[4]:= 'B';
Format2[5]:= '_OSD_YEAR4';
Format2[6]:= '-';
Format2[7]:= '_OSD_MONTH2';
Format2[8]:= '-' ;
Format2[9]:= '_OSD_DAY';
Format2[10]:= '\0' ;
SetOsdDisplayMode(1,255, true,1, @Format1, @Format2);
end;
=====================
是不是像这样呢?
还是不可以呀
var
Format1,Format2:array[0..40] of Word ;
_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:word;
begin
Format1[0]:=0;
Format1[1]:=0;
Format1[2]:= Ord(' ') ;
Format1[3]:= _OSD_YEAR4;
Format1[4]:= Ord('-') ;
Format1[5]:= _OSD_MONTH2;
Format1[6]:= Ord('-') ;
Format1[7]:= _OSD_DAY;
Format1[8]:= Ord(#0) ; Format2[0]:= Ord(#0) ;
SetOsdDisplayMode(0,255, false,1, @Format1, @Format2);
setosd(0,true); //这个是启动的
end; 你都沒有給_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND初始化,指定值。
_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:從文檔說明看,在它的dll中,應是代表代號。
看能不能查到_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND的相關信息
我刚刚看到,可以这样解决:
dim format1() as integer
dim format2() as integer
dim x as integer '想显示的坐标
dim y as integer '想显示的坐标
dim m as integer
dim strr1 as string
dim strr2 as stringstrr1=chr(x)+chr(y)+"郑州净瓶高科有限公司songyunly"+chr(0)
strr2=chr(x)+chr(y)+"2009-04-18 13:20:30""+chr(0)for m=1 to len(strr1)
format1(m-1)=Cint(asc(right(left(strr1,m),1)))
next m
for m=1 to len(strr2)
format2(m-1)=Cint(asc(right(left(strr1,m),1)))
next m
rs=SetOsdDisplayMode(0,255, false,1, Format1(0), Format2(0)); vb 语言写的抛砖引玉吧
Var
L, M, nLength: Integer;
Format1, Format2: Array[0..40] Of Word;
wFormat: Word;
Str: String;
wH, wL: Char;
Begin
L := 0;
Format1[0] := 8; //X坐标
Format1[1] := 22; //Y坐标
Str := IntToStr(ChannelNum + 1);
nLength := Length(Str);
M := 1;
While M < nLength + 1 Do
Begin
wH := Str[M];
wL := Str[M + 1];
If (Ord(wH) > 128) Then
Begin
M := M + 1;
wFormat := Ord(wH) * 16 * 16 + Ord(wL);
End
Else
wFormat := Ord(wH);
Format1[L + 2] := wFormat;
L := L + 1;
M := M + 1;
End;
Format1[L + 2] := Ord(#0);
//===============================================
Format2[0] := 8; //X坐标
Format2[1] := 5; //Y坐标
Format2[2] := _OSD_YEAR4;
Format2[3] := Ord('-');
Format2[4] := _OSD_MONTH2;
Format2[5] := Ord('-');
Format2[6] := _OSD_DAY;
Format2[7] := Ord(' ');
Format2[8] := _OSD_HOUR24;
Format2[9] := Ord(':');
Format2[10] := _OSD_MINUTE;
Format2[11] := Ord(':');
Format2[12] := _OSD_SECOND;
Format2[13] := Ord(#0);
//===============================================
HikVisionSDK.SetOsdDisplayMode(ChannelHandle[ChannelNum], 255, False, 0, @Format1, @Format2);
End;
你好!
1.附件是我们内测Demo以及预览代码。
2、关于Osd接口调用(主要部分),类似传参数给Format结构,例子是传CString到Format结构
USHORT Format1[40];
USHORT Format2[]={0,50,'海','康',' ',' ','年','1','1','1','1','\0'};
CString str="年1111Test";
int len=strlen(str);
LPTSTR pTemp=str.GetBuffer(0);
Format1[0]=Format1[1]=0; //显示位置坐标0,0
//copy第一个汉字,高位在前,地位在后
memcpy((UCHAR *)(Format1+2)+1,&pTemp[0],1);
memcpy((UCHAR *)(Format1+2),&pTemp[1],1);
len-=2; //剩余要显示的非汉字字符
for(int i=3;i<len+4;i++) //注意汉字只算一个字符,因此从i=3开始
{
Format1[i]=pTemp[i-1]; //字符串从2开始
}
Format1[len+4]='\0'; //显示字符数 加上表示显示位置的字符数
for(i = 0; i < GetTotalDSPs(); i++)
{
SetOsdDisplayMode(ChannelHandle[i], 255, TRUE, 1, Format1, Format2);
SetOsd(ChannelHandle[i], TRUE);
}
你这样子写就会显示实时时间了
L := 0;
Format1[0] := 24;
Format1[1] := 54;
//if 1=1 then begin
//str := '第' + '' + inttostr(i + 1) + '' + '路';
str:=Trim(Memo1.Text);
{if (RadioGroup2.ItemIndex = 0) then
begin
str := trim(edit4.Text);
end; }
nLength := Length(str);
m := 1;
while m < nLength+1 do begin
wH := str[m];
wL := str[m + 1];
if (ord(wH) > 128) then
begin
m := m + 1;
wFormat := ord(wH) * 16 * 16 + ord(wL);
end
else
wFormat := ord(wH);
Format1[L + 2] := wFormat;
L := L + 1;
m := m + 1;
end;
Format1[L + 2] := Ord(#0);
//end
//else
//Format1[2] := Ord(#0);
SetOsdDisplayMode(i, 255, false, 1, @Format1, @Format2);
Result := True;
Var
L, M, nLength: Integer;
Format1, Format2: Array[0..40] Of Word;
wFormat: Word;
Str: String;
wH, wL: Char;
Begin
L := 0;
Format1[0] := 8; //X坐标
Format1[1] := 32; //Y坐标
Str := '窗口'+IntToStr(ChannelNum + 1);
nLength := Length(Str);
M := 1;
While M < nLength + 1 Do
Begin
wH := Str[M];
wL := Str[M + 1];
If (Ord(wH) > 128) Then
Begin
M := M + 1;
wFormat := Ord(wH) * 16 * 16 + Ord(wL);
End
Else
wFormat := Ord(wH);
Format1[L + 2] := wFormat;
L := L + 1;
M := M + 1;
End;
Format1[L + 2] := Ord(#0);
//===============================================
Format2[0] := 8; //X坐标
Format2[1] := 5; //Y坐标
Format2[2] := _OSD_YEAR4;
Format2[3] := Ord('-');
Format2[4] := _OSD_MONTH2;
Format2[5] := Ord('-');
Format2[6] := _OSD_DAY;
Format2[7] := Ord(' ');
Format2[8] := _OSD_HOUR24;
Format2[9] := Ord(':');
Format2[10] := _OSD_MINUTE;
Format2[11] := Ord(':');
Format2[12] := _OSD_SECOND;
Format2[13] := Ord(' ');
Format2[14] := _OSD_CWEEK1 ;
Format2[15] := Ord(#0);
//===============================================
SetOsdDisplayMode(ChannelNum, 255, False, 1, @Format1, @Format2);
{
当值为1 时,OSD 的亮度根据背景的亮度来调整,但背景较亮时,OSD 亮度自动调低,但背景较暗时,OSD 亮度自动调亮。原来的闪烁功能关闭。
当值为 0 时, OSD的亮度不做调整
}
end;