C/C++程序中数字int、字符串string、char*之间的转换方法汇总

在写跨平台C/C++程序时,可能会用到数字int、字符串string、char*之间的转换,下面是一些方法的汇总:

  1. char * str转数字
int atoi (const char * str);//字符串转int

long int atol ( const char * str );//字符串转long

double atof (const char* str);//字符串转double
  1. 数字转char *
char *itoa(int value, char *string, int radix);//整数转字符串,radix是进制数

int sprintf( char *buffer, const char *format, [ argument] … );//可将整数转为字符串,如:

#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 1234;
char res[20];
sprintf(res, "%d", num);
printf("%s\n", res); //10进制字符串输出:1234

sprintf(res, "%0o", num);
printf("%s\n", res); //8进制字符串输出:2322 

sprintf(res, "%0x", num);
printf("%s\n", res); //16进制字符串输出:4d2
return 0;
}
  1. 数字类型转std::string
    std::string to_string (int val);
    std::string to_string (long val);
    std::string to_string (long long val);
    std::string to_string (unsigned val);
    std::string to_string (unsigned long val);
    std::string to_string (unsigned long long val);
    std::string to_string (float val);
    std::string to_string (double val);
    std::string to_string (long double val);
  1. std::string 与 char* 的转换:

string 转 char*

//方法1
std::string str = "hello world";
const char *p = str.data();

//方法2
std::string str = "hello world";
const char *p = str.c_str();

//方法3
std::string str = "hello world";
char p[40];
str.copy(p, 5, 0);//这里5,代表复制几个字符,0代表复制的位置 
*(p + 5) = '\0';//要手动加上结束符

char*转换为string:

const char* p = "Hello world"; 
std::string str = p; // 可以对str直接赋值 
cout << str; 
printf_s("%s", str.c_str());//printf_s直接打印会乱码,需要str.c_str()转换一下
  1. 常用的字符串操作函数:
      memset(res, '\0', sizeof(res));//清空字符数组(按字节对内存块进行初始化)    
      char *strcpy(char* dest, const char *src);//拷贝字符串  
      char *strcat(char *dest, const char *src);//连接两个字符串
 截取字符串:
      假设:string s = "0123456789";
string sub1 = s.substr(5); //只有一个数字5表示从下标为5开始一直到结尾:sub1 = "56789"
string sub2 = s.substr(5, 3); //从下标为5开始截取长度为3位:sub2 = "567"

访问string字符串中元素:

string s="12345";
cout<<s.at(1);//输出2
cout<<s[1];//输出2

字符串比较函数:
strcmp():strcmp(s1,s2); 比較两个字符串。
strncmp():strncmp(s1,s2); 比較两个字符串前n位
erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
erase(position);删除position处的一个字符(position是个string类型的迭代器)
erase(first,last);删除从first到last之间的字符(first和last都是迭代器)
比较规则:从左到右逐个字符进行比较(ASCII值),直到出现不同的字符或遇到’\0’为止。 假设所有的字符同样,则两字符串相等,返回值为0。
更多string的函数参考 https://blog.csdn.net/qq_37941471/article/details/82107077
假设出现不同的字符,则对第一次出现不同的字符进行比较。比较方法是以s1的第一个不同的字符减去s2的第一个不同的字符。以所得差值作为返回值(大于0。则返回1,小于0则返回-1)。
参考文章:
https://blog.csdn.net/u014801811/article/details/80113382
https://www.cnblogs.com/xudong-bupt/p/3479350.html

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
日历转换,阳历阴历 下载文件可以使用 package com.action.entity; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class Lunar { private int year; private int month; private int day; private boolean leap; private Calendar clendar; final static String chineseNumber[] = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" }; static SimpleDateFormat chineseDateFormat = new SimpleDateFormat( "yyyy年MM月dd日"); final static long[] lunarInfo = new long[] { 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 }; // Array lIntLunarDay is stored in the monthly day information in every year from 1901 to 2100 of the lunar calendar, // The lunar calendar can only be 29 or 30 days every month, express with 12(or 13) pieces of binary bit in one year, // it is 30 days for 1 form in the corresponding location , otherwise it is 29 days private static final int [] iLunarMonthDaysTable = { 0x4ae0 , 0xa570 , 0x5268 , 0xd260 , 0xd950 , 0x6aa8 , 0x56a0 , 0x9ad0 , 0x4ae8 , 0x4ae0 , // 1910 0xa4d8 , 0xa4d0 , 0xd250 , 0xd548 , 0xb550 , 0x56a0 , 0x96d0 , 0x95b0 , 0x49b8 , 0x49b0 , // 1920 0xa4b0 , 0xb258 , 0x6a50 , 0x6d40 , 0xada8 , 0x2b60 , 0x9570 , 0x4978 , 0x4970 , 0x64b0 , // 1930 0xd4a0 , 0xea50 , 0x6d48 , 0x5ad0 , 0x2b60 , 0x9370 , 0x92e0 , 0xc968 , 0xc950 , 0xd4a0 , // 1940 0xda50 , 0xb550 , 0x56a0 , 0xaad8 , 0x25d0 , 0x92d0 , 0xc958 , 0xa950 , 0xb4a8 , 0x6ca0 , // 1950 0xb550 , 0x55a8 , 0x4da0 , 0xa5b0 , 0x52b8 , 0x52b0 , 0xa950 , 0xe950 , 0x6aa0 , 0xad50 , // 1960 0xab50 , 0x4b60 , 0xa570 , 0xa570 , 0x5260 , 0xe930 , 0xd950 , 0x5aa8 , 0x56a0 , 0x96d0 , // 1970 0x4ae8 , 0x4ad0 , 0xa4d0 , 0xd268 , 0xd250 , 0xd528 , 0xb540 , 0xb6a0 , 0x96d0 , 0x95b0 , // 1980 0x49b0 , 0xa4b8 , 0xa4b0 , 0xb258 , 0x6a50 , 0x6d40 , 0xada0 , 0xab60 , 0x9370 , 0x4978 , // 1990 0x4970 , 0x64b0 , 0x6a50 , 0xea50 , 0x6b28 , 0x5ac0 , 0xab60 , 0x9368 , 0x92e0 , 0xc960 , // 2000 0xd4a8 , 0xd4a0 , 0xda50 , 0x5aa8 , 0x56a0 , 0xaad8 , 0x25d0 , 0x92d0 , 0xc958 , 0xa950 , // 2010 0xb4a0 , 0xb550 , 0xb550 , 0x55a8 , 0x4ba0 , 0xa5b0 , 0x52b8 , 0x52b0 , 0xa930 , 0x74a8 , // 2020 0x6aa0 , 0xad50 , 0x4da8 , 0x4b60 , 0x9570 , 0xa4e0 , 0xd260 , 0xe930 , 0xd530 , 0x5aa0 , // 2030 0x6b50 , 0x96d0 , 0x4ae8 , 0x4ad0 , 0xa4d0 , 0xd258 , 0xd250 , 0xd520 , 0xdaa0 , 0xb5a0 , // 2040 0x56d0 , 0x4ad8 , 0x49b0 , 0xa4b8 , 0xa4b0 , 0xaa50 , 0xb528 , 0x6d20 , 0xada0 , 0x55b0 // 2050 } ; // Array iLunarLeapMonthTable preserves the lunar calendar leap month from // 1901 to 2050, // if it is 0 express not to have , every byte was stored for two years private static final char[] iLunarLeapMonthTable = { 0x00, 0x50, 0x04, 0x00, 0x20, // 1910 0x60, 0x05, 0x00, 0x20, 0x70, // 1920 0x05, 0x00, 0x40, 0x02, 0x06, // 1930 0x00, 0x50, 0x03, 0x07, 0x00, // 1940 0x60, 0x04, 0x00, 0x20, 0x70, // 1950 0x05, 0x00, 0x30, 0x80, 0x06, // 1960 0x00, 0x40, 0x03, 0x07, 0x00, // 1970 0x50, 0x04, 0x08, 0x00, 0x60, // 1980 0x04, 0x0a, 0x00, 0x60, 0x05, // 1990 0x00, 0x30, 0x80, 0x05, 0x00, // 2000 0x40, 0x02, 0x07, 0x00, 0x50, // 2010 0x04, 0x09, 0x00, 0x60, 0x04, // 2020 0x00, 0x20, 0x60, 0x05, 0x00, // 2030 0x30, 0xb0, 0x06, 0x00, 0x50, // 2040 0x02, 0x07, 0x00, 0x50, 0x03 // 2050 }; // Array iSolarLunarTable stored the offset days // in New Year of solar calendar and lunar calendar from 1901 to 2050; private static final char[] iSolarLunarOffsetTable = { 49, 38, 28, 46, 34, 24, 43, 32, 21, 40, // 1910 29, 48, 36, 25, 44, 34, 22, 41, 31, 50, // 1920 38, 27, 46, 35, 23, 43, 32, 22, 40, 29, // 1930 47, 36, 25, 44, 34, 23, 41, 30, 49, 38, // 1940 26, 45, 35, 24, 43, 32, 21, 40, 28, 47, // 1950 36, 26, 44, 33, 23, 42, 30, 48, 38, 27, // 1960 45, 35, 24, 43, 32, 20, 39, 29, 47, 36, // 1970 26, 45, 33, 22, 41, 30, 48, 37, 27, 46, // 1980 35, 24, 43, 32, 50, 39, 28, 47, 36, 26, // 1990 45, 34, 22, 40, 30, 49, 37, 27, 46, 35, // 2000 23, 42, 31, 21, 39, 28, 48, 37, 25, 44, // 2010 33, 23, 41, 31, 50, 39, 28, 47, 35, 24, // 2020 42, 30, 21, 40, 28, 47, 36, 25, 43, 33, // 2030 22, 41, 30, 49, 37, 26, 44, 33, 23, 42, // 2040 31, 21, 40, 29, 47, 36, 25, 44, 32, 22, // 2050 }; // ====== 传回农历 y年的总天数 final private static int yearDays(int y) { int i, sum = 348; for (i = 0x8000; i > 0x8; i >>= 1) { if ((lunarInfo[y - 1900] & i) != 0) sum += 1; } return (sum + leapDays(y)); } // ====== 传回农历 y年闰月的天数 final private static int leapDays(int y) { if (leapMonth(y) != 0) { if ((lunarInfo[y - 1900] & 0x10000) != 0) return 30; else return 29; } else return 0; } // ====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0 final private static int leapMonth(int y) { return (int) (lunarInfo[y - 1900] & 0xf); } // ====== 传回农历 y年m月的总天数 final private static int monthDays(int y, int m) { if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) return 29; else return 30; } // ====== 传回农历 y年的生肖 final public String animalsYear() { final String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }; return Animals[(year - 4) % 12]; } // ====== 传入 月日的offset 传回干支, 0=甲子 final private static String cyclicalm(int num) { final String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" }; final String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" }; return (Gan[num % 10] + Zhi[num % 12]); } // ====== 传入 offset 传回干支, 0=甲子 final public String cyclical() { int num = year - 1900 + 36; return (cyclicalm(num)); } /** */ /** *   * 传出y年m月d日对应的农历.   * yearCyl3:农历年与1864的相差数 ?   * * monCyl4:从1900年1月31日以来,闰月数   * dayCyl5:与1900年1月31日相差的天数,再加40 ?   * @param * cal   * @return    */ public Lunar(Calendar cal) { this.clendar = cal; @SuppressWarnings("unused") int yearCyl, monCyl, dayCyl; int leapMonth = 0; Date baseDate = null; try { baseDate = chineseDateFormat.parse("1900年1月31日"); } catch (ParseException e) { e.printStackTrace(); // To change body of catch statement use // Options | File Templates. } // 求出和1900年1月31日相差的天数 int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L); dayCyl = offset + 40; monCyl = 14; // 用offset减去每农历年的天数 // 计算当天是农历第几天 // i最终结果是农历的年份 // offset是当年的第几天 int iYear, daysOfYear = 0; for (iYear = 1900; iYear 0; iYear++) { daysOfYear = yearDays(iYear); offset -= daysOfYear; monCyl += 12; } if (offset < 0) { offset += daysOfYear; iYear--; monCyl -= 12; } // 农历年份 year = iYear; yearCyl = iYear - 1864; leapMonth = leapMonth(iYear); // 闰哪个月,1-12 leap = false; // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天 int iMonth, daysOfMonth = 0; for (iMonth = 1; iMonth 0; iMonth++) { // 闰月 if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) { --iMonth; leap = true; daysOfMonth = leapDays(year); } else daysOfMonth = monthDays(year, iMonth); offset -= daysOfMonth; // 解除闰月 if (leap && iMonth == (leapMonth + 1)) leap = false; if (!leap) monCyl++; } // offset为0时,并且刚才计算的月份是闰月,要校正 if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { if (leap) { leap = false; } else { leap = true; --iMonth; --monCyl; } } // offset小于0时,也要校正 if (offset 0) { this.leap = true; } String dateStr =sCalendarLundarToSolar(year,month,day); try { Date d = chineseDateFormat.parse(dateStr); clendar = new GregorianCalendar(); clendar.setTime(d); } catch (ParseException e) { e.printStackTrace(); } } public static String sCalendarLundarToSolar(int iYear, int iMonth, int iDay) { int iSYear, iSMonth, iSDay; int iOffsetDays = iGetLNewYearOffsetDays(iYear, iMonth, iDay)+ iSolarLunarOffsetTable[iYear - 1901]; int iYearDays = bIsSolarLeapYear(iYear) ? 366 : 365; if (iOffsetDays >= iYearDays) { iSYear = iYear + 1; iOffsetDays -= iYearDays; } else { iSYear = iYear; } iSDay = iOffsetDays; for (iSMonth = 1; iOffsetDays >= 0; iSMonth++) { iSDay = iOffsetDays; iOffsetDays -= iGetSYearMonthDays(iSYear, iSMonth); } iSMonth--; return iSYear +"年"+iSMonth + "月"+ iSDay + "日"; } public static int iGetLNewYearOffsetDays(int iYear, int iMonth, int iDay) { int iOffsetDays = 0; int iLeapMonth = iGetLLeapMonth(iYear); if ((iLeapMonth > 0) && (iLeapMonth == iMonth - 12)) { iMonth = iLeapMonth; iOffsetDays += iGetLMonthDays(iYear, iMonth); } for (int i = 1; i < iMonth; i++) { iOffsetDays += iGetLMonthDays(iYear, i); if (i == iLeapMonth) iOffsetDays += iGetLMonthDays(iYear, iLeapMonth + 12); } iOffsetDays += iDay - 1; return iOffsetDays; } public static boolean bIsSolarLeapYear(int iYear) { return ((iYear % 4 == 0) && (iYear % 100 != 0) || iYear % 400 == 0); } // The days in the month of solar calendar static int iGetSYearMonthDays(int iYear, int iMonth) { if ((iMonth == 1) || (iMonth == 3) || (iMonth == 5) || (iMonth == 7) || (iMonth == 8) || (iMonth == 10) || (iMonth == 12)) return 31; else if ((iMonth == 4) || (iMonth == 6) || (iMonth == 9) || (iMonth == 11)) return 30; else if (iMonth == 2) { if (bIsSolarLeapYear(iYear)) return 29; else return 28; } else return 0; } // The offset days from New Year and the day when point out in solar // calendar public static int iGetSNewYearOffsetDays(int iYear, int iMonth, int iDay) { int iOffsetDays = 0; for (int i = 1; i > 4; } public static int iGetLMonthDays(int iYear, int iMonth) { int iLeapMonth = iGetLLeapMonth(iYear); if ((iMonth > 12) && (iMonth - 12 != iLeapMonth) || (iMonth > iLeapMonth)) == 0) return 29; else return 30; } if ((iLeapMonth > 0) && (iMonth > iLeapMonth)) iMonth++; if ((iLunarMonthDaysTable[iYear - 1901] & (0x8000 >> (iMonth - 1))) == 0) return 29; else return 30; } // Days in this year of lunar calendar public static int iGetLYearDays(int iYear) { int iYearDays = 0; int iLeapMonth = iGetLLeapMonth(iYear); for (int i = 1; i 0) iYearDays += iGetLMonthDays(iYear, iLeapMonth + 12); return iYearDays; } public static String getChinaDayString(int day) { String chineseTen[] = { "初", "十", "廿", "卅" }; int n = day % 10 == 0 ? 9 : day % 10 - 1; if (day > 30) return ""; if (day == 10) return "初十"; else return chineseTen[day / 10] + chineseNumber[n]; } public int getYear() { return year; } public void setYear(int year) {
using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; namespace DS40XXSDK { #region enum /// <summary> /// 板卡类型 /// </summary> public enum BOARD_TYPE_DS : uint { DS400XM = 0, //M卡 DS400XH = 1, //H卡 DS4004HC = 2, //4004HC DS4008HC = 3, //4008HC DS4016HC = 4, //4016HC DS4001HF = 5, //4001HF DS4004HF = 6, //4004HF DS4002MD = 7, //4002MD DS4004MD = 8, //4004MD DS4016HCS = 9, //4016HCS DS4002HT = 10, //4002HT DS4004HT = 11, //4004HT DS4008HT = 12, //4008HT DS4004HC_PLUS = 13, //4004HC+ DS4008HC_PLUS = 14, //4008HC+ DS4016HC_PLUS = 15, //4016HC+ DS4008HF = 16, //4008HF DS4008MD = 17, //4008MD DS4008HS = 18, //4008HS DS4016HS = 19, //4016HS INVALID_BOARD_TYPE = 0xffffffff, } /// <summary> /// 视频预览格式 /// </summary> public enum TypeVideoFormat { vdfRGB8A_233 = 0x00000001, vdfRGB8R_332 = 0x00000002, vdfRGB15Alpha = 0x00000004, /// <summary> /// 16位RGB视频压缩格式 /// </summary> vdfRGB16 = 0x00000008, /// <summary> /// 24位RGB视频压缩格式 /// </summary> vdfRGB24 = 0x00000010, vdfRGB24Alpha = 0x00000020, vdfYUV420Planar = 0x00000040, /// <summary> /// YUV422视频压缩格式 /// </summary> vdfYUV422Planar = 0x00000080, vdfYUV411Planar = 0x00000100, vdfYUV420Interspersed = 0x00000200, vdfYUV422Interspersed = 0x00000400, vdfYUV411Interspersed = 0x00000800, vdfYUV422Sequence = 0x00001000, /* U0, Y0, V0, Y1: For VO overlay */ vdfYUV422SequenceAlpha = 0x00002000, /* U0, Y0, V0, Y1: For VO overlay, with low bit for alpha blending */ vdfMono = 0x00004000, /* 8 bit monochrome */ vdfYUV444Planar = 0x00008000, }; /// <summary> /// 视频制式 /// </summary> public enum VideoStandard_t : uint { /// <summary> /// 无视频信号 /// </summary> StandardNone = 0x80000000, /// <summary> /// NTSC制式 /// </summary> StandardNTSC = 0x00000001, /// <summary> /// PAL制式 /// </summary> StandardPAL = 0x00000002, StandardSECAM = 0x00000004, } ; /// <summary> /// 编码图像分辨率 /// </summary> public enum PictureFormat_t { ENC_CIF_FORMAT = 0, ENC_QCIF_FORMAT = 1, ENC_2CIF_FORMAT = 2, ENC_4CIF_FORMAT = 3, ENC_QQCIF_FORMAT = 4, ENC_CIFQCIF_FORMAT = 5, ENC_CIFQQCIF_FORMAT = 6, ENC_DCIF_FORMAT = 7 }; /// <summary> /// 码流控制方式 /// </summary> public enum BitrateControlType_t { /// <summary> /// 变码率 /// </summary> brCBR = 0, /// <summary> /// 恒定码率 /// </summary> brVBR = 1, }; public enum FrameType_t { PktError = 0, PktIFrames = 0x0001, PktPFrames = 0x0002, PktBBPFrames = 0x0004, PktAudioFrames = 0x0008, PktMotionDetection = 0x00010, PktDspStatus = 0x00020, PktOrigImage = 0x00040, PktSysHeader = 0x00080, PktBPFrames = 0x00100, PktSFrames = 0x00200, PktSubIFrames = 0x00400, PktSubPFrames = 0x00800, PktSubBBPFrames = 0x01000, PktSubSysHeader = 0x02000 }; #endregion #region struct /// <summary> /// 板卡信息结构体 /// </summary> public struct DS_BOARD_DETAIL { /// <summary> /// 板卡类型 /// </summary> BOARD_TYPE_DS type; /// <summary> /// 序列号 /// BYTE sn[16]; /// </summary> [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] byte[] sn; /// <summary> /// 板卡包含的DSP个数 /// </summary> uint dspCount; /// <summary> /// 板卡上第一个DSP的索引 /// </summary> uint firstDspIndex; /// <summary> /// 板卡包含的编码通道个数 /// </summary> uint encodeChannelCount; /// <summary> /// 板卡上第一个编码通道的索引 /// </summary> uint firstEncodeChannelIndex; /// <summary> /// 板卡包含的解码通道个数 /// </summary> uint decodeChannelCount; /// <summary> /// 板卡上第一个解码通道的索引 /// </summary> uint firstDecodeChannelIndex; /// <summary> /// 板卡包含的视频输出通道个数 /// </summary> uint displayChannelCount; /// <summary> /// 板卡上第一个视频输出通道的索引 /// </summary> uint firstDisplayChannelIndex; uint reserved1; uint reserved2; uint reserved3; /// <summary> /// 硬件版本,format:major.minor.build,major:bit 16-19,minor: bit 8-15,build: bit 0-7 /// </summary> uint version; } /// <summary> /// DSP信息结构体 /// </summary> public struct DSP_DETAIL { /// <summary> /// 此DSP所包含的编码通道个数 /// </summary> uint encodeChannelCount; /// <summary> /// 此DSP上第一个编码通道在所有编码通道的索引 /// </summary> uint firstEncodeChannelIndex; /// <summary> /// 此DSP所包含的解码通道个数 /// </summary> uint decodeChannelCount; /// <summary> /// 此DSP上第一个解码通道在所有解码通道的索引 /// </summary> uint firstDecodeChannelIndex; /// <summary> /// 此DSP包含的显示通道个数 /// </summary> uint displayChannelCount; /// <summary> /// 此DSP上第一个显示通道在所有显示通道的索引 /// </summary> uint firstDisplayChannelIndex; uint reserved1; uint reserved2; uint reserved3; uint reserved4; } /// <summary> /// 特殊功能结构体 /// </summary> public struct CHANNEL_CAPABILITY { /// <summary> /// 音频预览 /// </summary> byte[] bAudioPreview; /// <summary> /// 报警信号 /// </summary> byte[] bAlarmIO; /// <summary> /// 看家狗 /// </summary> byte[] bWatchDog; } /// <summary> /// 版本信息 /// </summary> public struct PVERSION_INFO { /// <summary> /// DSP版本号,DSP的BUILD号,用于软件升级时标明该版本的最后修改时间 /// </summary> UInt64 DspVersion, DspBuildNum; /// <summary> /// Driver版本号,Driver的BUILD号,用于软件升级时标明该版本的最后修改时间 /// </summary> UInt64 DriverVersion, DriverBuildNum; /// <summary> /// SDK版本号,SDK的BUILD号,用于软件升级时标明该版本的最后修改时间 /// </summary> UInt64 SDKVersion, SDKBuildNum; } /// <summary> /// 显示窗口内的矩形区域 /// </summary> //[StructLayout(LayoutKind. //public struct RECT //{ // public Int32 left; // public Int32 top; // public Int32 right; // public Int32 bottom; //} /// <summary> /// 帧统计信息结构体 /// </summary> public struct PFRAMES_STATISTICS { /// <summary> /// 视频帧 /// </summary> UInt64 VideoFrames; /// <summary> /// 音频帧 /// </summary> UInt64 AudioFrames; /// <summary> /// 丢失帧 /// </summary> UInt64 FramesLost; /// <summary> /// 丢失的码流(字节) /// </summary> UInt64 QueueOverflow; /// <summary> /// 当前的帧率(bps) /// </summary> UInt64 CurBps; } /// <summary> /// 版本信息结构体 /// </summary> public struct PHW_VERSION { /// <summary> /// DSP程序的版本号和Build号 /// </summary> UInt64 DspVersion, DspBuildNum; /// <summary> /// 驱动程序的版本号和Build号 /// </summary> UInt64 DriverVersion, DriverBuildNum; /// <summary> /// SDK 的版本号和Build号 /// </summary> UInt64 SDKVersion, SDKBuildNum; } /// <summary> /// 系统时间 /// </summary> public struct SYSTEMTIME { ushort wYear; ushort wMonth; ushort wDayOfWeek; ushort wDay; ushort wHour; ushort wMinute; ushort wSecond; ushort wMilliseconds; } #endregion #region delegate /// <summary> /// 原始图像流设置 /// /// typedef void (*IMAGE_STREAM_CALLBACK)(UINT channelNumber,void *context); /// </summary> /// <param name="channelNumber">通道号</param> /// <param name="context">设备上下文</param> public delegate void IMAGE_STREAM_CALLBACK(uint channelNumber, IntPtr context); /// <summary> /// 编码数据流直接读取回调函数 /// /// typedef int (*STREAM_DIRECT_READ_CALLBACK)(UInt64 channelNumber,void *DataBuf,DWORD Length,int FrameType,void *context); /// </summary> /// <param name="channelNumber">通道号</param> /// <param name="DataBuf">缓冲区地址</param> /// <param name="Length">缓冲区长度</param> /// <param name="FrameType">缓冲区数据帧类型</param> /// <param name="context">设备上下文</param> /// <returns></returns> [UnmanagedFunctionPointer(CallingConvention.Cdecl)] //public delegate int STREAM_DIRECT_READ_CALLBACK(uint channelNumber, byte[] DataBuf, uint Length, FrameType_t FrameType, IntPtr context); public delegate int STREAM_DIRECT_READ_CALLBACK(int channelNumber, IntPtr DataBuf, int Length, FrameType_t FrameType, IntPtr context); //public unsafe delegate int STREAM_DIRECT_READ_CALLBACK(uint channelNumber, void * DataBuf, uint Length, int FrameType, IntPtr context); /// <summary> /// 直接读取码流回调函数 /// /// typedef int (*STREAM_READ_CALLBACK)(UInt64 channelNumber, void *context) /// </summary> /// <param name="channelNumber">通道号</param> /// <param name="context">设备上下文</param> /// <returns></returns> public delegate int STREAM_READ_CALLBACK(UInt64 channelNumber, IntPtr context); /// <summary> /// 移动侦测结果回调函数 /// /// typedef void (*MOTION_DETECTION_CALLBACK)(UInt64 channelNumber, BOOL bMotionDetected,void *context) /// </summary> /// <param name="channelNumber">通道号</param> /// <param name="bMotionDetected"> /// 移动侦测发生标志,如果当前通道所设置的移动侦测 /// 区域内产生了移动侦测,则被置为True;如果当前通道所设置的移动侦测区域内自上 /// 一次产生移动侦测后delay秒内没有发生移动侦测,则被置为False。 /// </param> /// <param name="context">设备上下文</param> public delegate void MOTION_DETECTION_CALLBACK(UInt64 channelNumber, bool bMotionDetected, IntPtr context); /// <summary> /// 画图回调函数 /// /// #define DRAWFUN(x) void (CALLBACK* x)(Int32 nPort,HDC hDc,Int32 nUser) /// </summary> /// <param name="nPort">通道号</param> /// <param name="HDC">offscreen表面设备上下文,相当于显示窗口的DC</param> /// <param name="nUser">用户数据</param> public delegate void DrawFun(Int32 nPort, IntPtr HDC, Int32 nUser); /// <summary> /// 解码回调函数 /// /// typedef void (*DECODER_VIDEO_CAPTURE_CALLBACK)(UINT nChannelNumber, void *DataBuf,UINT width,UINT height,UINT nFrameNum,UINT nFrameTime, SYSTEMTIME *pFrameAbsoluteTime,void *context) /// </summary> /// <param name="nChannelNumber">解码通道句柄</param> /// <param name="DataBuf">缓冲区地址</param> /// <param name="width">图像宽度</param> /// <param name="height">图像高度</param> /// <param name="nFrameNum">捕获的当前帧的序号</param> /// <param name="nFrameTime">捕获的当前帧的相对时间,单位:毫秒</param> /// <param name="pFrameAbsoluteTime">捕获的当前帧的绝对时间</param> /// <param name="context">设备上下文</param> public delegate void DECODER_VIDEO_CAPTURE_CALLBACK(uint nChannelNumber, IntPtr DataBuf, uint width, uint height, uint nFrameNum, uint nFrameTime, SYSTEMTIME pFrameAbsoluteTime, IntPtr context); /// <summary> /// 创建索引完成回调函数 /// /// typedef void (*FILE_REF_DONE_CALLBACK)(UINT nChannel,UINT nSize) /// </summary> /// <param name="nChannel">通道号</param> /// <param name="nSize">索引大小(暂时无效,以后可以增加索引导出、导入功能) </param> public delegate void FILE_REF_DONE_CALLBACK(uint nChannel, uint nSize); #endregion /// <summary> /// DS40xxSDK.dll /// </summary> public class HikVisionSDK { /// <summary> /// 状态 /// </summary> public static readonly List<string> state = new List<string>(new string[]{ "", "正在打开", "音频信号丢失", "视频信号丢失", "有物体移动", //0-4 "自动分割录像", "开始录像", "停止录像", "启动声音监听", "停止声音监听", //5-9 "启动视频预览", "停止视频预览", "启动录像", "停止录像", "启动视频报警", //10-14 "关闭视频报警", "启动音频报警", "停止音频报警", "启动移动侦测", "停止移动侦测", //15-19 "启动视频遮挡", "关闭视频遮挡", "开始屏幕输出", "停止屏幕输出", "启动视频LOGO", //20-24 "停止视频LOGO", "开始视频OSD", "停止视频OSD", "切换为黑白视频", "切换为彩色视频", //25-29 "切换为黑屏显示", "切换为白屏显示", "视频色彩复位", "启动全屏显示", "采集卡已经加载", //30-34 "采集卡已经卸截", "视频服务启动成功", "视频服务已停止", "静音", "音量恢复", //35-39 "云台控制命令发送", "系统出现未知错误", "录像文件大小", "配置端口号成功", "连接服务端成功", //40-44 "正在连接", "开始接收图象", "异常退出", "接收完毕,退出", "无法联系服务端", //45-49 "服务端拒绝访问", "无效", "停止客户端连接", "图像抓取成功", "初始化服务端网络连接成功", //50-54 "视频服务启动失败", "退出全屏预览", "", "", "" //55-59 }); //可以用新版函数替代功能或者无效的API //GetTotalChannels:可用GetEncodeChannelCount替代 //GetTotalDSPs:可用GetDspCount 替代 //SetupDateTime:4.0版本起无效 //HW_GetChannelNum:无效,请使用GetBoardDetail //HW_GetDeviceSerialNo:无效,请使用GetBoardDetail //HW_SetVideoOutStandard:无效,请使用SetDisplayStandard或SetDefaultVideoStandard //HW_SetDspDeadlockMsg:无效 //HW_ResetDsp:无效 //HW_SetDisplayPara:DISPLAY_PARA结构bToVideoOut无效,MD卡模拟视频输出功能 //已经整合到视频矩阵之。 #region 流类型宏定义 /// <summary> /// 视频流 /// #define STREAM_TYPE_VIDEO /// </summary> private const int STREAM_TYPE_VIDEO = 1; /// <summary> /// 音频流 /// #define STREAM_TYPE_AUDIO /// </summary> private const int STREAM_TYPE_AUDIO = 2; /// <summary> /// 音视频复合流 /// #define STREAM_TYPE_AVSYNC /// </summary> private const int STREAM_TYPE_AVSYNC = 3; #endregion #region 1.板卡初始化及卸载 /// <summary> /// 1.1初始化DSP InitDSPs /// 说 明: 初始化系统每一块板卡,应在应用软件程序启动时完成。如果返回值为0则表 /// 明初始化失败,可能没有找到相应的DSP软件模块。 /// /// int __stdcall InitDSPs() /// </summary> /// <returns>系统内可用的编码通道个数。 </returns> [DllImport("DS40xxSDK.dll")] public static extern int InitDSPs(); /// <summary> /// 1.2卸载DSP DeInitDSPs /// 说 明: 关闭每一块板卡上的功能,应在应用软件程序退出时调用。 /// /// int __stdcall DeInitDSPs() /// </summary> /// <returns>0</returns> [DllImport("DS40xxSDK.dll")] public static extern int DeInitDSPs(); #endregion #region 2.板卡信息获取 /// <summary> /// 2.1获取系统板卡的张数GetBoardCount /// 说 明: 获取系统所有板卡的张数,包含编码卡和解码卡。 /// /// unsigned int __stdcall GetBoardCount() /// </summary> /// <returns>系统板卡的总张数。</returns> [DllImport("DS40xxSDK.dll")] public static extern uint GetBoardCount(); /// <summary> /// 2.2获取系统DSP的个数GetDspCount /// 说 明: 获取系统所有板卡的DSP的个数。 /// /// unsigned int __stdcall GetDspCount() /// </summary> /// <returns>系统DSP的总个数</returns> [DllImport("DS40xxSDK.dll")] public static extern uint GetDspCount(); /// <summary> /// GetTotalDSPs:可用GetDspCount 替代 /// 获得实际可用DSP /// </summary> /// <returns></returns> [DllImport("DS40xxSDK.dll")] public static extern int GetTotalDSPs(); /// <summary> /// 2.3获取系统编码通道的个数GetEncodeChannelCount /// 说 明: 获取系统所有编码卡的编码通道总个数,包含H系列和HC系列编码卡。 /// /// unsigned int __stdcall GetEncodeChannelCount() /// </summary> /// <returns>系统编码通道的个数</returns> [DllImport("DS40xxSDK.dll")] public static extern uint GetEncodeChannelCount(); /// <summary> /// 2.4获取系统解码通道的个数GetDecodeChannelCount /// 说 明: 获取系统MD卡的解码通道个数 /// /// unsigned int __stdcall GetDecodeChannelCount() /// </summary> /// <returns></returns> [DllImport("DS40xxSDK.dll")] public static extern uint GetDecodeChannelCount(); /// <summary> /// 2.5获取系统解码显示通道的个数GetDisplayChannelCount /// 说 明: 获取系统MD卡显示通道的个数,即模拟视频输出通道的个数 /// /// unsigned int __stdcall GetDisplayChannelCount() /// </summary> /// <returns>系统显示通道的个数</returns> [DllImport("DS40xxSDK.dll")] public static extern uint GetDisplayChannelCount(); /// <summary> /// 2.6获取板卡详细信息GetBoardDetail /// 说 明: 获取某张板卡的详细信息 /// /// int __stdcall GetBoardDetail(UINT boardNum,DS_BOARD_DETAIL *pBoardDetail) /// </summary> /// <param name="boardNum">板卡索引</param> /// <param name="pBoardDetail">板卡信息</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetBoardDetail(uint boardNum, ref DS_BOARD_DETAIL pBoardDetail); /// <summary> /// 2.7获取DSP详细信息GetDspDetail /// 说 明: 获取某个DSP的详细信息 /// /// int __stdcall GetDspDetail(UINT dspNum,DSP_DETAIL *pDspDetail) /// </summary> /// <param name="dspNum">DSP索引</param> /// <param name="pDspDetail">DSP信息</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetDspDetail(uint dspNum, ref DSP_DETAIL pDspDetail); /// <summary> /// 2.8获取板卡型号及序列号信息GetBoardInfo /// 说 明: 获取板卡的型号及序列号信息 /// /// int __stdcall GetBoardInfo(HANDLE hChannelHandle, UInt64 *BoardType, UCHAR *SerialNo) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="BoardType">板卡型号</param> /// <param name="SerialNo"> /// 板卡ID号, 内容为板卡序列号的ASCII的数值,次序为SerialNo[0] 对应最高位, /// SerialNo[11]对应最低位。比如卡号为“40000002345”的值对应为 4,0,0,0,0,1,0,0,2,3,4,5 的整形数组。 /// </param> /// <returns>成功为0;失败返回错误号 </returns> [DllImport("DS40xxSDK.dll")] public static extern int GetBoardInfo(IntPtr hChannelHandle, UInt64 BoardType, byte[] SerialNo); /// <summary> /// 2.9获取板卡特殊功能信息GetCapability /// 说 明: 获取板卡特殊功能信息 /// /// int __stdcall GetCapability(HANDLE hChannelHandle, CHANNEL_CAPABILITY *Capability) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="Capability">特殊功能 </param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetCapability(IntPtr hChannelHandle, CHANNEL_CAPABILITY Capability); /// <summary> /// 2.10获取板卡SDK信息GetSDKVersion /// 说 明: 获取当前所使用的DSP、Driver、SDK版本号 /// /// int __stdcall GetSDKVersion(PVERSION_INFO VersionInfo) /// </summary> /// <param name="VersionInfo">版本信息</param> /// <returns>成功返回0;失败返回错误号。</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetSDKVersion(ref PVERSION_INFO VersionInfo); /// <summary> /// 2.11获取板卡SDK及DSP错误报告GetLastErrorNum*,此函数只对H卡有效 /// 说 明: 获取SDK及DSP错误报告。此函数只对H卡有效,用于HC卡上返回0且无效 /// /// int __stdcall GetLastErrorNum(HANDLE hChannelHandle, UInt64 *DspError, UInt64 *SdkError) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="DspError">DSP错误</param> /// <param name="SdkError">SDK错误</param> /// <returns>DSP错误信息、SDK错误信息</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetLastErrorNum(IntPtr hChannelHandle, ref int DspError, ref int SdkError); #endregion #region 3.编码卡API #region 3.1通道打开及关闭 /// <summary> /// 3.1.1打开通道ChannelOpen /// 说 明: 打开通道,获取编码通道的操作句柄,与通道相关的操作需使用相对应的句柄。 /// /// HANDLE __stdcall ChannelOpen(int ChannelNum) /// </summary> /// <param name="ChannelNum">通道号(从0开始)</param> /// <returns>成功返回有效句柄(值可能为0);失败返回0xFFFFFFFF。</returns> [DllImport("DS40xxSDK.dll")] public static extern IntPtr ChannelOpen(int ChannelNum); /// <summary> /// 3.1.2关闭通道ChannelClose /// 说 明: 关闭通道,释放相关资源 /// /// int __stdcall ChannelClose(HANDLE hChannelHandle) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int ChannelClose(IntPtr hChannelHandle); #endregion #region 3.2视频预览 #region 3.2.1 Overlay预览模式 // 释 义: overlay预览模式 //Overlay通常被称为重叠页面或者是覆盖层,是一种需要特定的硬件支持的页面,通常 //被用于显示实时视频于主页面之上,而不需要Blit操作到主页面或用任何方法改变主页面的 //内容。使用该方式进行预览可以提高预览的画质和降低CPU利用率。 /// <summary> /// 3.2.1.1设置视频预览模式SetPreviewOverlayMode /// 说 明: SDK自3.2版本起在部分显卡实现了HC卡以overlay方式预览的功能(此功 /// 能不支持与H卡混插的状态下),可以提高预览的画质和降低CPU利用率。当预览画面小 /// 于704*576时,需要调用该函数来启动overlay模式,如不设置则自动切换到offscreen模式 /// 进行预览显示,当预览画面大于704*576时,SDK自动切换到overlay模式 /// /// int __stdcall SetPreviewOverlayMode(BOOL bTrue) /// </summary> /// <param name="bTrue">是否设置overlay预览方式,也适用于MD卡</param> /// <returns>0表示显卡支持板卡的overlay预览方式;其他值表示显卡不支持 </returns> [DllImport("DS40xxSDK.dll")] public static extern int SetPreviewOverlayMode(bool bTrue); /// <summary> /// 3.2.1.2设置overlay关键色SetOverlayColorKey /// 注意:需要在StartVideoPreview前调用该函数。 /// 说 明: 板卡在显示范围小于704*576时,调用SetPreviewOverlayMode可以开启overlay /// 预览模式,需调用SetOverlayColorKey设置overlay关键色;当显示范围大于704*576时, /// 板卡自动切换到overlay预览模式,关键色默认设置为RGB(10,10,10),也可调用 /// SetOverlayColorKey修改关键色。在这两种情况下,都需要将显示窗口的底色设置为和关键 /// 色相一致。否则图像将难以显示。 /// /// /// int __stdcall SetOverlayColorKey(COLORREF DestColorKey) /// </summary> /// <param name="DestColorKey">overlay关键色参数(RGB(*,*,*))</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetOverlayColorKey(int DestColorKey); //public static extern int SetOverlayColorKey(Color DestColorKey); /// <summary> /// 3.2.1.3恢复当前丢失的表面RestoreOverlay /// 说 明: 恢复当前丢失的表面,例如:当系统按下CTRL+ALT+DEL时系统的OVERLAY /// 表面会被强制关闭,调用该函数可以恢复OVERLAY表面 /// /// int __stdcall RestoreOverlay() /// </summary> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int RestoreOverlay(); #endregion #region 3.2.2 开启及停止视频预览 /// <summary> /// 3.2.2.1开启视频预览StartVideoPreview /// 说 明: 启动视频预览,调用SetPreviewOverlayMode后,可进行overlay模式预览,否则, /// 将默认采用offscreen模式预览。当画面大于704*576时,SDK自动切换到overlay预览模式。 /// /// int __stdcall StartVideoPreview(HANDLE hChannelHandle,HWND WndHandle, RECT *rect,BOOLEAN bOverlay, int VideoFormat, int FrameRate) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="WndHandle">显示窗口句柄</param> /// <param name="rect"> /// 显示窗口内的矩形区域 /// Rect.right 必须为8的倍数 /// Rect.bottom必须为16的倍数 /// </param> /// <param name="bOverlay">是否启用Overlay预览模式</param> /// <param name="VideoFormat">视频预览格式(目前无效)</param> /// <param name="FrameRate">视频预览帧率(PAL:1-25,NTSC:1-30)</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int StartVideoPreview(IntPtr hChannelHandle, IntPtr WndHandle, ref Rectangle rect, bool bOverlay, int VideoFormat, int FrameRate); //public static extern int StartVideoPreview(IntPtr hChannelHandle, IntPtr WndHandle, ref RECT rect, bool bOverlay, int VideoFormat, int FrameRate); /// <summary> /// 3.2.2.2停止视频预览StopVideoPreview /// 说 明: 停止视频预览 /// /// int __stdcall StopVideoPreview(HANDLE hChannelHandle) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int StopVideoPreview(IntPtr hChannelHandle); #endregion #region 3.2.3 视频参数的设置及获取 /// <summary> /// 3.2.3.1设置视频参数SetVideoPara /// 说 明: 设置视频参数 /// /// int __stdcall SetVideoPara(HANDLE hChannelHandle, int Brightness, int Contrast, int Saturation, int Hue) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="Brightness">亮度值(0-255)</param> /// <param name="Contrast">对比度(0-127)</param> /// <param name="Saturation">饱和度(0-127)</param> /// <param name="Hue">色调(0-255)</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetVideoPara(IntPtr hChannelHandle, int Brightness, int Contrast, int Saturation, int Hue); /// <summary> /// 3.2.3.2获取视频参数GetVideoPara /// 说 明: 获取视频参数 /// /// int __stdcall GetVideoPara(HANDLE hChannelHandle, VideoStandard_t *VideoStandard, int*Brightness, int *Contrast, int *Saturation, int *Hue) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="VideoStandard">视频制式</param> /// <param name="Brightness">亮度指针值(0-255)</param> /// <param name="Contrast">对比度指针值(0-127)</param> /// <param name="Saturation">饱和度指针值(0-127)</param> /// <param name="Hue">色调指针值(0-255)</param> /// <returns> 成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetVideoPara(IntPtr hChannelHandle, VideoStandard_t VideoStandard, out int Brightness, out int Contrast, out int Saturation, out int Hue); #endregion #endregion #region 3.3视频信号设置(制式、状况、输入位置等) /// <summary> /// 3.3.1设置视频制式SetVideoStandard,此函数只对H卡有效 /// 说 明: 设置视频制式,在某一制式的摄像头已经接好的情况下启动系统时可不必调用该 /// 函数,如果没有接摄像头的情况下启动系统然后再接NTSC制式的摄像头则必须调用该函 /// 数,或者途调换不同制式的摄像头也必须调用该函数。 /// /// int __stdcall SetVideoStandard(HANDLE hChannelHandle, VideoStandard_t VideoStandard) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="VideoStandard">视频制式</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetVideoStandard(IntPtr hChannelHandle, VideoStandard_t VideoStandard); /// <summary> /// 3.3.2设置系统默认的视频制式SetDefaultVideoStandard /// 注意:该函数只能在系统初始化(InitDSPs)之前运行,否则无效 /// 说 明: 设置系统默认的视频制式,系统所有的视频输入通道如果无视频输入或者在系 /// 统启动的时候,通道会按照所设置的系统默认视频制式进行处理。 /// /// int __stdcall SetDefaultVideoStandard(VideoStandard_t VideoStandard) /// </summary> /// <param name="VideoStandard">视频制式,默认为PAL </param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetDefaultVideoStandard(VideoStandard_t VideoStandard); /// <summary> /// 3.3.3设置视频信号灵敏度SetVideoDetectPrecision /// 说 明: 设置视频信号检测的灵敏度。如果视频信号的强度比较弱,或者信号通断的切换 /// 比较频繁,会出现“无视频信号”的提示字样,为了避免提示字样影响图像,可以更改视频 /// 信号检测的灵敏度。灵敏度取值越大,检测精度越低,出现“无视频信号”提示字样的频率 /// 越低。当将value值设置为0xffffffff时,将不会再出现“无视频信号”的提示字样。 /// /// int __stdcall SetVideoDetectPrecision(HANDLE hChannel,unsigned int value) /// </summary> /// <param name="hChannel">通道句柄</param> /// <param name="value">灵敏度。取值范围:0-100,默认为20</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetVideoDetectPrecision(IntPtr hChannel, uint value); /// <summary> /// 3.3.4获取视频信号输入情况GetVideoSignal /// 说 明: 获取视频信号的输入情况,用于视频丢失报警 /// /// int __stdcall GetVideoSignal(HANDLE hChannelHandle) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <returns>信号正常返回0;返回其他值说明信号异常或有错误</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetVideoSignal(IntPtr hChannelHandle); /// <summary> /// 3.3.5调整视频信号输入位置SetInputVideoPosition /// 说 明: 设置视频信号的输入位置。(x,y)为系统处理图像的左上角在摄像机输入的原 /// 始图像的坐标,某些摄像机输入的图像在预览时可能在左边会有黑边,可以通过此函数进 /// 行调节,x必须设置为2的整数倍。(x,y)的取值和摄像机的型号有关,如果指定的值和 /// 摄像机的输入参数不匹配,可能会导致图像静止、水平垂直方向滚动或者黑屏,请谨慎使用。 /// /// int __stdcall SetInputVideoPosition(HANDLE hChannel,UINT x,UINT y) /// </summary> /// <param name="hChannel">通道句柄</param> /// <param name="x">X轴坐标,默认值为8</param> /// <param name="y">Y轴坐标,默认值为2</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetInputVideoPosition(IntPtr hChannel, uint x, uint y); /// <summary> /// 3.3.6设置反隔行变换及强度SetDeInterlace /// 说 明: 设置是否采用反隔行算法,已经采用反隔行时的强度 /// /// 释 义: 反隔行变换 /// 如果该通道的图像需要进行4CIF的预览或编码,此时的图像会同时包含奇、偶两 /// 场的数据,由于奇场图像和偶场图像不同步,导致图像运动的部分发生错位、边缘模糊, /// 此时需要对图像进行反隔行变换来去掉这种现象。如果用户能够确定使用的是逐行扫描格式 /// 的摄像机,或者主要应用在静止场景,此时可以关掉反隔行变换功能,或者降低强度,这样 /// 可以提高系统运行效率,并降低反隔行变换对图像质量带来的损失。 /// /// int __stdcall SetDeInterlace(HANDLE hChannelHandle,UINT mode,UINT level) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="mode"> /// 0表示该通道不进行反隔行变换,此时level参数无效; /// 1表示使用旧的算法; /// 2表示使用默认算法(系统默认值)。 /// </param> /// <param name="level"> /// mode=1时有效,其它时无效。 /// 0-10,反隔行变换的强度逐渐加强,0最弱,对图像的损失最小,10最强,对图像的损失最大。 /// </param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetDeInterlace(IntPtr hChannelHandle, uint mode, uint level); #endregion #region 3.4视频编码参数设置 // 释 义: 双编码功能(主、子通道) // 对一路视频图像进行两路视频编码,两路视频可以有不同的码流类型、不同分辨率、不 //同码率等。3.0版本对双编码功能做了增强,子通道的所有参数都可以任意设置。 //双编码主通道和子通道唯一的区别在于:子通道占用的系统资源比主通道少,优先级 //比主通道低。当系统忙时,会尽量保证主通道编码,并先从子通道开始丢帧。由于占用资源 //少,因此可以利用子通道来实现多路高分辨率的非实时编码。例如:可以把DS-4000HC //的每个子通道全部设置为4CIF分辨率(SetSubStreamType),而不使用主通道编码,这样就 //可以实现全部通道的4CIF编码。在一般场景下,每路图像都可以达到15帧以上。 /// <summary> /// 3.4.1主、子通道切换SetupSubChannel /// 说 明: 配合双编码模式使用。当设置某个通道为双编码模式时,如主通道编码CIF,子 /// 通道编码QCIF,这时可对主/子通道分别设置某些参数。关键帧间隔、OSD、LOGO等参数 /// 对主/子通道是一样的;在设置帧率、量化系数、变码流/定码流模式、码流大小等参数时应 /// 调用此函数分别对主/子通道进行设置,缺省是对主通道进行设置 /// /// int __stdcall SetupSubChannel(HANDLE hChannelHandle, int iSubChannel) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="iSubChannel">子通道号(0表示主通道,1表示主通道)</param> /// <returns>成功返回0;失败返回错误号 </returns> [DllImport("DS40xxSDK.dll")] public static extern int SetupSubChannel(IntPtr hChannelHandle, int iSubChannel); /// <summary> /// 3.4.2获取双编码时数据流类型GetSubChannelStreamType /// 说 明: 配合双编码模式使用,当设置双编码模式时,启动录像后,DSP会向上送两种 /// 数据流,调用此函数得到主通道和子通道的数据流类型,供应用程序使用。 /// /// int __stdcall GetSubChannelStreamType(void *DataBuf, int FrameType) /// </summary> /// <param name="DataBuf">数据缓存区</param> /// <param name="FrameType">帧类型</param> /// <returns> /// 0 其他数据 /// 1 主通道数据流的文件头 /// 2 子通道数据流的文件头 /// 3 主通道数据流的视频帧类型 /// 4 子通道数据流的视频帧类型 /// 5 数据流的音频帧 /// </returns> [DllImport("DS40xxSDK.dll")] public static extern int GetSubChannelStreamType(IntPtr DataBuf, int FrameType); #region 3.4.3编码流类型的设置及获取(不支持动态修改) /// <summary> /// 3.4.3.1设置主通道编码流类型SetStreamType /// 说 明: 设置主通道编码流类型。此函数需在启动编码前进行设置 /// /// int __stdcall SetStreamType(HANDLE hChannelHandle, USHORT Type) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="Type">流类型</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetStreamType(IntPtr hChannelHandle, ushort Type); /// <summary> /// 3.4.3.2获取主通道编码流类型GetStreamType /// 说 明: 获取主通道编码流类型 /// /// int __stdcall GetStreamType(HANDLE hChannelHandle, USHORT *StreamType) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="StreamType">流类型</param> /// <returns>成功返回0;失败返回错误号 </returns> [DllImport("DS40xxSDK.dll")] public static extern int GetStreamType(IntPtr hChannelHandle, ref ushort StreamType); /// <summary> /// 3.4.3.3设置子通道编码流类型SetSubStreamType /// 说 明: 设置子通道编码流类型,此函数需在启动编码前进行设置 /// /// int __stdcall SetSubStreamType(HANDLE hChannelHandle, USHORT Type) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="Type">流类型</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetSubStreamType(IntPtr hChannelHandle, ref ushort Type); /// <summary> /// 3.4.3.4获取子通道编码流类型GetSubStreamType /// 说 明: 获取子通道编码流类型 /// /// int __stdcall GetSubStreamType(HANDLE hChannelHandle, USHORT *StreamType) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="StreamType">流类型</param> /// <returns></returns> [DllImport("DS40xxSDK.dll")] public static extern int GetSubStreamType(IntPtr hChannelHandle, ref ushort StreamType); #endregion #region 3.4.4(支持动态修改)的编码参数设置 /// <summary> /// 3.4.4.1设置编码图像质量SetDefaultQuant /// 说 明: 设置图像量化系数,用于调整图像质量。量化系数越小图像质量越高。系统默认量化系数值为18,18,23。 /// 释 义: 量化系数 /// 量化系数是强烈影响MPEG标准编码图像质量和码率的参数,当量化系数越低,图 /// 像质量就会越高,码率也就越高,反之,图形质量就会越低,码率也就越低 /// /// int __stdcall SetDefaultQuant(HANDLE hChannelHandle, int IQuantVal, int PQuantVal, int BQuantVal) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="IQuantVal">I帧量化系数,取值范围:12-30</param> /// <param name="PQuantVal">P帧量化系数。取值范围:12-30(目前无效)</param> /// <param name="BQuantVal">B帧量化系数。取值范围:12-30(目前无效)</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetDefaultQuant(IntPtr hChannelHandle, int IQuantVal, int PQuantVal, int BQuantVal); /// <summary> /// 3.4.4.2设置编码帧结构、帧率SetIBPMode /// 说 明: 设置编码帧结构和帧率。支持动态修改 /// 释 义: 关键帧间隔 /// 关键帧为编码码流采用帧内压缩的图像帧,其特点是图像清晰度好,但数据量大,通 /// 常作为帧间编码的原始参考帧。关键帧间隔是连续的帧间编码的帧个数,因H264(MPEG4) /// 编码是有损压缩,关键帧的个数会影响图像质量,因此关键帧的间隔需要合理设计。 /// /// int __stdcall SetIBPMode(HANDLE hChannelHandle, int KeyFrameIntervals, int BFrames, int PFrames, int FrameRate) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="KeyFrameIntervals">关键帧间隔。取值范围1-400,系统默认为100</param> /// <param name="BFrames">B帧数量,取值为0或者2,系统默认为2 </param> /// <param name="PFrames">P帧数量。目前暂取值无效</param> /// <param name="FrameRate">帧率,帧率范围1-25(PAL)、1-30(NTSC)</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetIBPMode(IntPtr hChannelHandle, int KeyFrameIntervals, int BFrames, int PFrames, int FrameRate); #region 3.4.4.3设置编码分辨率 /// <summary> /// 3.4.4.3.1设置主通道分辨率SetEncoderPictureFormat /// 说 明: 设置主通道编码分辨率。支持动态修改。 /// /// int __stdcall SetEncoderPictureFormat(HANDLE hChannelHandle, PictureFormat_t PictureFormat) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="PictureFormat">编码图像分辨率(4CIF、DCIF、2CIF、CIF、QCIF) </param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetEncoderPictureFormat(IntPtr hChannelHandle, PictureFormat_t PictureFormat); /// <summary> /// 3.4.4.3.2设置子通道编码分辨率SetSubEncoderPictureFormat /// 说 明: 设置双编码模式时子通道的编码分辨率,支持动态修改。 /// /// int __stdcall SetSubEncoderPictureFormat(HANDLE hChannelHandle, PictureFormat_t PictureFormat) /// </summary> /// <param name="hChannelHandle">子通道句柄</param> /// <param name="PictureFormat">子通道编码图像分辨率(4CIF、DCIF、2CIF、CIF、 QCIF) </param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetSubEncoderPictureFormat(IntPtr hChannelHandle, PictureFormat_t PictureFormat); #endregion #region 3.4.4.4设置码率及码流控制模式 /// <summary> /// 3.4.4.4.1设置码流最大比特率SetupBitrateControl /// 说 明: 设置编码的最大比特率。设置为0时码流控制无效,设置为某一最大比特率时, /// 当编码码流超过该值时,DSP会自动调整编码参数来保证不超过最大比特率,当编码码流 /// 低于最大比特率时,DSP不进行干涉。调整误差<10% /// /// int __stdcall SetupBitrateControl(HANDLE hChannelHandle, UInt64 MaxBps) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="MaxBps">最大比特率。取值:10000以上</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetupBitrateControl(IntPtr hChannelHandle, Int32 MaxBps); /// <summary> /// 3.4.4.4.2设置码流控制方式SetBitrateControlMode /// 说 明: 设置编码码流控制方式。配合SetupBitrateControl使用。当设置为变码率(brVBR) /// 时,最大比特率将作为编码码流上限,由DSP在码流上限下自动控制码率,一般会自动回 /// 落到最低的状态(由设定的图像质量参数和关键帧间隔决定),能最大程度地降低带宽和存 /// 储空间,但存储容量一般难以估算;当设置为定码率(brCBR)时,以最大比特率作为编码 /// 码率参数恒定输出码流,不会自动回落到低码流状态,存储容量可根据设定码率的大小进行估算。 /// /// int __stdcall SetBitrateControlMode(HANDLE hChannelHandle, BitrateControlType_t brc) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="brc">码流控制方式,分为变码率(brVBR)和恒定码率 (brCBR)两种方式 </param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetBitrateControlMode(IntPtr hChannelHandle, BitrateControlType_t brc); #endregion /// <summary> /// 3.4.5强制设定I帧CaptureIFrame /// 说 明: 将当前编码帧强制设定为I帧模式,可从码流提取该帧单独用于网络传送。 /// /// int __stdcall CaptureIFrame(HANDLE hChannelHandle) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int CaptureIFrame(IntPtr hChannelHandle); /// <summary> /// 3.4.6获取帧统计信息GetFramesStatistics /// 说 明: 获取帧统计信息 /// /// int __stdcall GetFramesStatistics(HANDLE hChannelHandle,PFRAMES_STATISTICS framesStatistics) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="framesStatistics">帧统计信息</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetFramesStatistics(IntPtr hChannelHandle, PFRAMES_STATISTICS framesStatistics); #endregion #endregion #region 3.5数据捕获 #region 3.5.1抓图(获取单帧图像数据) #region 3.5.1.1抓取BMP格式图像 /// <summary> /// 3.5.1.1.1获取原始yuv422格式数据GetOriginalImage /// 说 明: 获得原始yuv422格式图像,DS4000HC原始图像是4CIF图像格式(包括QCIF编码), /// DS-4000HS原始图像为CIF图像格式,DS400xH卡的原始图象是CIF图象格式。 /// /// int __stdcall GetOriginalImage(HANDLE hChannelHandle, UCHAR *ImageBuf, UInt64 *Size) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="ImageBuf">原始yuv422格式图像指针</param> /// <param name="Size">原始yuv422格式图像尺寸,函数调用前是ImageBuf的大小,调用后是实际图像所占用的字节数 </param> /// <returns>成功返回0,失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int GetOriginalImage(IntPtr hChannelHandle, byte[] ImageBuf, out int Size); /// <summary> /// 3.5.1.1.2图像格式转换YUVtoBMP SaveYUVToBmpFile /// 说 明: 用户程序可调用此函数来生成24位的bmp文件,如果是DS4000HC卡抓图则 /// Width 为704,Height 为576PAL/480NTSC,如果是DS400xH卡抓图则Width可能为352 /// 或176,Height为288、240、144或120,要根据缓冲区的大小来判断。 /// /// int __stdcall SaveYUVToBmpFile(char *FileName, unsigned char *yuv, int Width, int Height) /// </summary> /// <param name="FileName">文件名</param> /// <param name="yuv">yuv422格式图像指针</param> /// <param name="Width">图像宽度</param> /// <param name="Height">图像高度</param> /// <returns></returns> [DllImport("DS40xxSDK.dll")] public static extern int SaveYUVToBmpFile(string FileName, byte[] yuv, int Width, int Height); /// <summary> /// 3.5.1.2抓取JPEG格式图像GetJpegImage /// 说 明: 抓取JPEG格式图像 /// /// int __stdcall GetJpegImage(HANDLE hChannelHandle,UCHAR *ImageBuf, UInt64 *Size,UINT nQuality) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="ImageBuf">JPEG图像指针</param> /// <param name="Size">JPEG图像尺寸,函数调用前是ImageBuf的大小,调用后是实际图像所占用的字节数 </param> /// <param name="nQuality">JPEG图像质量,取值范围1-100,取值100时质量最好</param> /// <returns></returns> [DllImport("DS40xxSDK.dll")] public static extern int GetJpegImage(IntPtr hChannelHandle, byte[] ImageBuf, out int Size, uint nQuality); #endregion #region 3.5.2原始图像数据流捕获(获取YUV420格式数据流) /// <summary> /// 3.5.2.1注册原始图像数据流回调函数RegisterImageStreamCallback /// 说 明: 注册获取原始图像数据流函数,用户可以获取实时的YUV420格式的预览数据 /// /// int __stdcall RegisterImageStreamCallback (IMAGE_STREAM_CALLBACK ImageStreamCallback,void *context) /// </summary> /// <param name="ImageStreamCallback">原始图像数据流回调函数 </param> /// <param name="context">设备上下文</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int RegisterImageStreamCallback(IMAGE_STREAM_CALLBACK ImageStreamCallback, IntPtr context); /// <summary> /// 3.5.2.2开启及停止原始数据流捕获SetImageStream /// 说明: 开启或停止原始图像数据流捕获,此函数依赖主机的处理速度。DS-4000HS只能捕获不大于CIF格式的数据流 /// /// 函 数: int __stdcall SetImageStream(HANDLE hChannel,BOOL bStart,UINT fps, UINT width,UINT height,unsigned char *imageBuffer) /// </summary> /// <param name="hChannel">通道句柄</param> /// <param name="bStart">是否启动捕获</param> /// <param name="fps">帧率</param> /// <param name="width">图像宽度,必须是4CIF宽度的1/8,1/4,1/2或原始大小704</param> /// <param name="height">图象高度,必须是4CIF高度的1/8,1/4,1/2或原始大小576PAL/480NTSC</param> /// <param name="imageBuffer">数据存储缓存</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetImageStream(IntPtr hChannel, bool bStart, uint fps, uint width, uint height, char[] imageBuffer); #endregion #region 3.5.3编码数据流捕获(获取编码后H.264格式数据流)即录像 //注意:注册直接回调或者消息回调后,需要启动编码数据流捕获函数才能进行数据回调。三 //种数据回调方式,只需选取其一种使用即可。对于HC系列板卡(包括HC、HC+、HCS、 //HS),推荐使用第一种读取方式。对于H系列板卡,只能使用后两种读取方式。 #region 3.5.3.1编码数据流捕获方式设置 /// <summary> /// 3.5.3.1.1.1注册编码图像数据流直接读取回调函数 /// 说 明: DS4000HC系列板卡新增的一种数据流读取方式,当启动数据捕获后, /// StreamDirectReadCallback会提供数据流的地址、长度、帧类型等,供用户程序直接处理。 /// /// 函 数: int __stdcall RegisterStreamDirectReadCallback (STREAM_DIRECT_READ_CALLBACK StreamDirectReadCallback,void *Context) /// </summary> /// <param name="StreamDirectReadCallback">编码数据流直接读取回调函数</param> /// <param name="context">设备上下文</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int RegisterStreamDirectReadCallback(STREAM_DIRECT_READ_CALLBACK StreamDirectReadCallback, IntPtr context); #endregion #region 3.5.3.1.2方式二、消息读取方式 /// <summary> /// 3.5.3.1.2.1设置消息读取伐值,此函数只对H卡有效 /// 说 明: 设置消息读取的伐值,可以将缓冲区的数据在OnDataReady一次性取走 /// /// int __stdcall SetupNotifyThreshold(HANDLE hChannelHandle, int iFramesThreshold) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="iFramesThreshold">读取消息伐值,范围1-10</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int SetupNotifyThreshold(IntPtr hChannelHandle, int iFramesThreshold); /// <summary> /// 3.5.3.1.2.2注册消息读取码流函数 /// 说 明: 当数据准备好时,SDK会向hWnd窗口发送MessageId消息,目标窗口收到 /// Message后调用ReadStreamData读取一帧数据。如果HC卡与H卡混插,可以先调用 /// RegisterStreamDirectReadCallback函数来注册HC卡取码流回调函数,再调用 /// RegisterMessageNotifyHandle函数来注册H卡取码流消息函数。 /// HC系列板卡建议使用方式一进行数据捕获。 /// /// int __stdcall RegisterMessageNotifyHandle(HWND hWnd, UINT MessageId) /// </summary> /// <param name="hWnd">通道句柄</param> /// <param name="MessageId">自定义消息</param> /// <returns>成功返回0;失败返回错误号 </returns> [DllImport("DS40xxSDK.dll")] public static extern int RegisterMessageNotifyHandle(IntPtr hWnd, uint MessageId); #endregion #region 3.5.3.1.3方式三、另一种直接读取方式 /// <summary> /// 3.5.3.1.3.1注册直接读取码流回调函数 /// 说 明: 另一种数据流读取方式 /// /// int __stdcall RegisterStreamReadCallback (STREAM_READ_CALLBACK StreamReadCallback, void *Context) /// </summary> /// <param name="StreamReadCallback">直接读取码流回调函数</param> /// <param name="Context">设备上下文</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int RegisterStreamReadCallback(STREAM_READ_CALLBACK StreamReadCallback, IntPtr Context); #endregion /// <summary> /// 3.5.3.2读取码流函数 /// 说 明: 读指定长度的数据流,适用于方式二及方式三。当调用StartVideoCapture 或 /// StartMotionDetection后,SDK线程会向已注册的用户窗口消息处理函数发送指定的消息, /// 并提供消息来源的通道号。当用户程序收到该消息时,可调用本函数来读取数据,Length 在 /// 作为输入时必须提供缓冲的大小,ReadStreamData会判断缓冲是否足够,如果缓冲足够大 /// 则返回值为当前的读取的帧长度,否则返回错误。 /// 在HC卡,如果已经先调用了RegisterStreamDirectReadCallback()函数,则不需调用 /// ReadStreamData来读取数据,因为音视频数据会在RegisterStreamDirectReadCallback所注册 /// 的回调函数直接返回。 /// /// int __stdcall ReadStreamData(HANDLE hChannelHandle, void *DataBuf, DWORD *Length, int *FrameType) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <param name="DataBuf">自定义的数据缓存区</param> /// <param name="Length">输入:缓存区的大小;输出:一帧数据的大小</param> /// <param name="FrameType">帧类型</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int ReadStreamData(IntPtr hChannelHandle, byte[] DataBuf, out UInt64 Length, out int FrameType); #region 3.5.3.3开启及停止录像 /// <summary> /// 3.5.3.3.1启动主通道编码数据流捕获 /// 说 明: 启动主通道编码数据流捕获。用户程序可以使用直接读取方式,使用 /// StreamDirectReadCallback回调函数直接对数据流进行处理;也可以与H卡一样,通过消息 /// 读取方式,等SDK向用户程序发送在RegisterMessageNotifyHandle注册的消息,用户程 /// 序使用ReadStreamData来读取数据流。 /// /// int __stdcall StartVideoCapture(HANDLE hChannelHandle) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int StartVideoCapture(IntPtr hChannelHandle); /// <summary> /// 3.5.3.3.2停止主通道编码数据流捕获 /// 说 明: 停止主通道编码数据流捕获 /// /// int __stdcall StopVideoCapture(HANDLE hChannelHandle) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int StopVideoCapture(IntPtr hChannelHandle); /// <summary> /// 3.5.3.3.3启动子通道编码数据流捕获 /// 说 明: 启动子通道编码数据流捕获 /// /// int __stdcall StartSubVideoCapture(HANDLE hChannelHandle) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <returns>成功返回0;失败返回错误号</returns> [DllImport("DS40xxSDK.dll")] public static extern int StartSubVideoCapture(IntPtr hChannelHandle); /// <summary> /// 3.5.3.3.4停止子通道编码数据流捕获 /// 说 明: 停止子通道编码数据流捕获 /// /// int __stdcall StopSubVideoCapture(HANDLE hChannelHandle) /// </summary> /// <param name="hChannelHandle">通道句柄</param> /// <returns>成功返回0;失败返回错误号 </returns> [DllImport("DS40xxSDK.dll")] public static extern int StopSubVideoCapture(IntPtr hChannelHandle); #endregion #endregion #endregion #endregion #region 3.6移动侦测 // 释 义: 移动侦测 //DS4000HC提供运动强度信息来处理运动检测,设置移动侦测区域时以32*32像素块为 //单位,按4CIF(704*576)分辨率计算,每行有22个块(704/32),PAL时18行(576/32), //NTSC时15行(480/32),与编码格式无关。经过测试,这种方法比H卡提高了灵敏度和可 //靠性,并简化了返回的数据,返回的值是18个DWORD,对应屏幕高度576/32=18行(PAL), //每个DWORD的0-21位对应屏幕宽度704/32=22, 其1为运动,0为静止,也可以调用原有 //MotionAnalyzer分析结果 //4.0版本的SDK新增了接口函数SetupMotionDetectionEx,
unit CnDigits;{-------------------------------------------------------------------- 货币数字为为文大写的组件 Version 1.31 by SNAKEJIAO 2003.4.13简介: 可以化整数,浮点数,及时间日期型数据 配合别名列表可以进行语音合成,主要用于 东进继卡的PlayPrompt提示语音的合成 用于电话系统播放金额,日期及时间 还有输入的数字序列,同时更多的应用于显示 销售系统的打印发票时的文大写金额字段email: jiaoguoqing26@21cn.com来自:爱数星星的猫, 时间:2003-9-17 没有习惯,有规定。给你看看人民银行的规定吧(说不定你还得改改^_^)。正确填写票据和结算凭证的基本规定 银行、单位和个人填写的各种票据和结算凭证是办理支付结算和现金收付的重要依据,直接关系到支付结算的准确、及时和安全。票据和结算凭证是银行、单位和个人凭以记载账务的会计凭证,是记载经济业务和明确经济责任的一种书面证明。因此,填写票据和结算凭证,必须做到标准化、规范化,要要素齐全、数字正确、字迹清晰、不错漏、不潦草,防止涂改。 一、文大写金额数字应用正楷或行书填写,如壹(壹)、贰(贰)、叁、肆(肆)、伍(伍)、陆(陆)、柒、捌、玖、拾、佰、仟、万(万)、亿、元、角、分、零、整(正)等字样。不得用一、二(两)、三、四、五、六、七、八、九、十、念、毛、另(或0)填写,不得自造简化字。如果金额数字书写使用繁体字,如貳、陸、億、萬、圓的,也应受理。 二、文大写金额数字到“元”为止的,在“元”之后,应写“整”(或“正”)字,在“角”之后可以不写“整”(或“正”)字。大写金额数字有“分”的,“分”后面不写“整”(或“正”)字。 三、文大写金额数字前应标明“人民币”字样,大写金额数字应紧接“人民币”字样填写,不得留有空白。大写金额数字前未印“人民币”字样的,应加填“人民币”三字。在票据和结算凭证大写金额栏内不得预印固定的“仟、佰、拾、万、仟、伯、拾、元、角、分”字样。 四、阿拉伯小写金额数字有“0”时,文大写应按照汉语语言规律、金额数字构成和防止涂改的要求进行书写。举例如下: (一)阿拉伯数字间有“O”时,文大写金额要写“零”字。如 ¥1,409.50,应写成人民币壹仟肆佰零玖元伍角。 (二)阿拉伯数字间连续有几个“0”时,文大写金额间可以只写 一个“零”字。如¥6,007.14,应写成人民币陆仟零柒元壹角肆分。 (三)阿拉伯金额数字万位或元位是“0”,或者数字间连续有几个“0”, 万位、元位也是“0’,但千位、角位不是“0”时,文大写金额 可以只写一个零字,也可以不写“零”字。如¥1,680.32,应写成 人民币壹仟陆佰捌拾元零叁角贰分,或者写成人民币壹仟陆佰捌拾元 叁角贰分;又如¥107,000.53,应写成人民币壹拾万柒仟元零伍角 叁分,或者写成人民币壹拾万零柒仟元伍角叁分。 (四)阿拉伯金额数字角位是“0”,而分位不是“0”时,文大写金额 “元”后面应写“零”字。如¥16,409.02,应写成人民币壹万陆 仟肆佰零玖元零贰分;又如¥325.04,应写成人民币叁佰贰拾伍元 零肆分。 五、阿拉伯小写金额数字前面,均应填写入民币符号“¥”(或草写:)。阿拉伯小写金额数字要认真填写,不得连写分辨不清。 六、票据的出票日期必须使用文大写。为防止变造票据的出禀日期,在填写月、日时,月为壹、贰和壹拾的,日为壹至玖和壹拾、贰拾和叁抬的,应在其前加“零”;日为抬壹至拾玖的,应在其前加“壹”。如1月15日,应写成零壹月壹拾伍日。再如10月20日,应写成零壹拾月零贰拾日。 七、票据出票日期使用小写填写的,银行不予受理。大写日期未按要求规范填写的,银行可予受理,但由此造成损失的,由出票入自行承担。--------------------------------------------------------------------}{ ‘NOTICE: uncomment following line to discard unused code !‘}{ ‘注意: 去掉下面这一行,可以抛弃收集的其它代码‘}// { discard_other_code}interfaceuses Windows, Messages, SysUtils, Classes, Math;type //类型定义 TDate = TDateTime; TTime = TDateTime; { 数字大写组件 by lichaohui } TCnDigits = class(TComponent) private Fda: Boolean; procedure SetDA(const Value: Boolean); procedure SetCnUP(const Value: String); protected FCurrVa: Currency; FCnUpDigits: String; FAlias: TStrings; procedure SetCurrVa(const Value: Currency); procedure SetAlias(const Value: TStrings); public { discard_other_code} //下面是肖杨的商场管理源码的代码 //返加人民币的文数值 class function other_RMB(NN:real):string; //其它的两个方法 class function other_SmallTOBig(small: real): string; class function other_XD(xx: currency): string; {} //下面是lichaohui的工具函数 class function LzhFmtInt(IntValue: Int64; IsYear: Boolean = False; SoftTone: Boolean = False): String; class function LzhFmtDigits(Digits: String): String; class function LzhFmtFloat(FloatValue: Extended; RoundPos: Integer = 8): String; class function LzhFmtCurrency(AValue: Currency): String; overload; class function LzhFmtCurrency(AValue: Int64): String; overload; class function LzhFmtDate(AValue: TDate; DigitsYear: Boolean = False): String; class function StdFmtDate(AValue: TDate; DigitsYear: Boolean = False): String; class function LzhFmtTime(AValue: TTime; HasSecond: Boolean = False): String; class function LzhFmtDateTime(AValue: TDateTime; DigitsYear: Boolean = False): String; class function StdFmtDateTime(AValue: TDateTime; DigitsYear: Boolean = False): String; //常用方法调用接口 function ChineseUpper(Curr: Currency): String; function ChineseDate(ADate: TDate; DigitsYear: Boolean = False): String; function ChineseTime(ATime: TTime; HasSecond: Boolean = False): String; //等价别名化 function StrToAlias(S: String): String; function StrToAlias2(S: String): String; //构造和析构函数 constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property CurrencyValue: Currency read FCurrVa write SetCurrVa; property CnUpperDigits: String read FCnUpDigits write SetCnUP stored False; property Alias: TStrings read FAlias write SetAlias; property DefaultAlias: Boolean read Fda write SetDA; end;const DP: WideString = ‘零壹贰叁肆伍陆柒捌玖两负‘; DN: WideString = ‘点拾佰仟万拾佰仟亿拾佰仟万拾佰仟兆拾佰仟‘; CrNa: WideString = ‘元角分整‘; DtNa: WideString = ‘年月日时分秒‘;procedure Register;implementationprocedure Register;begin RegisterComponents(‘System‘, [TCnDigits]);end;{ TCnDigits }{ discard_other_code}class function TCnDigits.other_RMB(NN: real): string;var HZ, NS, NW, NA, N1, N2:string; LA, X, Nk:integer;begin //此行代码是为了修正小数位多于两位时生成的结果的错误 NN := Int(NN * 100) / 100; //下面的代码被lichaohui格式化整理 if NN > 9999999999999.99 then begin //MessageDlg(‘金额溢出。‘,mtError,[mbOk], 0); HZ := ‘‘; Result := HZ; exit; end; if NN = 0 then begin HZ := ‘零元‘; result := HZ; exit; end; NS := ‘零壹贰叁肆伍陆柒捌玖‘; NW := ‘分角元拾佰仟万拾佰仟亿拾佰仟万‘; NA := FloatToStr(NN * 100); LA := length(NA); X := 1; HZ := ‘‘; while X<=LA do begin NK := Ord(NA[x]) - Ord(‘0‘); N1 := Copy(NS, NK * 2 + 1, 2); N2 := Copy(NW, LA * 2 + 1 - X * 2, 2); if (NK = 0) AND ((N2 = ‘亿‘) OR( N2 = ‘万‘) OR( N2 = ‘元‘))then begin if copy(HZ,Length(HZ)-1,2) = ‘零‘ then HZ := copy(HZ, 1, length(HZ) - 2); if copy(HZ, Length(HZ) - 1, 2) = ‘亿‘ then if N2 = ‘元‘ then begin N1 := N2; N2 := ‘零‘; end else N2 := ‘‘ else begin N1 := N2; N2 := ‘零‘; end end else if NK=0 then begin if copy(HZ, length(HZ) - 1, 2)=‘零‘ then N1 := ‘‘; if N2=‘分‘ then begin if copy(HZ, length(HZ) - 1, 2)=‘零‘ then HZ := copy(HZ, 1, length(HZ) - 2) + ‘整‘ else HZ := HZ + ‘整‘; N1 := ‘‘; end; N2 := ‘‘; end; HZ := HZ + N1 + N2; X := X + 1 end; {end of while statement} Result := HZ;end;class function TCnDigits.other_SmallTOBig(small: real): string;var SmallMonth,BigMonth:string; wei1,qianwei1:string[2]; qianwei,dianweizhi,qian:integer;begin {------- 修改参数令值更精确 -------} {小数点后的位数,需要的话也可以改动该值} qianwei:=-2; {转换成货币形式,需要的话小数点后加多几个零} Smallmonth:=formatfloat(‘0.00‘,small); {---------------------------------} dianweizhi :=pos(‘.‘,Smallmonth);{小数点的位置} {循环小写货币的每一位,从小写的右边位置到左边} for qian:=length(Smallmonth) downto 1 do begin {如果读到的不是小数点就继续} if qiandianweizhi then begin {位置上的数转换成大写} case strtoint(copy(Smallmonth,qian,1)) of 1:wei1:=‘壹‘; 2:wei1:=‘贰‘; 3:wei1:=‘叁‘; 4:wei1:=‘肆‘; 5:wei1:=‘伍‘; 6:wei1:=‘陆‘; 7:wei1:=‘柒‘; 8:wei1:=‘捌‘; 9:wei1:=‘玖‘; 0:wei1:=‘零‘; end; {判断大写位置,可以继续增大到real类型的最大值,可是谁有那么多钱} case qianwei of -3:qianwei1:=‘厘‘; -2:qianwei1:=‘分‘; -1:qianwei1:=‘角‘; 0 :qianwei1:=‘元‘; 1 :qianwei1:=‘拾‘; 2 :qianwei1:=‘佰‘; 3 :qianwei1:=‘千‘; 4 :qianwei1:=‘万‘; 5 :qianwei1:=‘拾‘; 6 :qianwei1:=‘佰‘; 7 :qianwei1:=‘千‘; 8 :qianwei1:=‘亿‘; 9 :qianwei1:=‘拾‘; 10:qianwei1:=‘佰‘; 11:qianwei1:=‘千‘; end; inc(qianwei); BigMonth :=wei1+qianwei1+BigMonth;{组合成大写金额} end; end; Result := BigMonth;end;class function TCnDigits.other_XD(xx: currency): string;var dx,ws:string; i,cd:integer; int:currency;begin int:=trunc(abs(xx)+0.005*100); cd:=length(currtostr(int)); dx:=‘零壹贰叁肆伍陆柒捌玖‘; ws:=‘分角元拾佰仟万拾佰仟亿拾佰仟‘; result:=‘‘; i:=1; while i 0) and (FracPart >= 10) then rs := rs + DP[1]; if (IntPart = 0) and (FracPart 0) then rs := ‘‘; if FracPart >= 10 then begin if FracPart mod 10 = 0 then rs := rs + DP[Jiao + 1] + CrNa[2] + CrNa[4] else rs := rs + DP[Jiao + 1] + CrNa[2] + DP[Fen + 1] + CrNa[3]; end else if FracPart > 0 then begin if IntPart = 0 then rs := rs + DP[Fen + 1] + CrNa[3] else rs := rs + DP[1] + DP[Fen + 1] + CrNa[3]; end else begin rs := rs + CrNa[4]; end; if AValue 0) and (FracPart >= 10) then rs := rs + DP[1]; if (IntPart = 0) and (FracPart 0) then rs := ‘‘; if FracPart >= 10 then begin if FracPart mod 10 = 0 then rs := rs + DP[Jiao + 1] + CrNa[2] + CrNa[4] else rs := rs + DP[Jiao + 1] + CrNa[2] + DP[Fen + 1] + CrNa[3]; end else if FracPart > 0 then begin if IntPart = 0 then rs := rs + DP[Fen + 1] + CrNa[3] else rs := rs + DP[1] + DP[Fen + 1] + CrNa[3]; end else begin rs := rs + CrNa[4]; end; if AValue = ‘0‘) and (Digits[i] 1e15) or (FloatValue 16 then rps := 16; beit := IntPower(10, rps); FraPart := Round(Frac(FloatValue) * beit); rs := LzhFmtInt(IntPart); if FraPart > 0 then begin Digits := IntToStr(FraPart); len := Length(Digits); while (len > 0) and (Digits[len] = ‘0‘) do len := len - 1; Digits := Copy(Digits, 1, len); rs := rs + DN[1] + LzhFmtDigits(Digits); end; if FloatValue < 0 then rs := DP[12] + rs; Result := rs;end;class function TCnDigits.LzhFmtInt(IntValue: Int64; IsYear: Boolean; SoftTone: Boolean): String;var i, n, t: Integer; bi: WideString; LastBt: WideChar; rs: WideString; reach: Boolean; LastHit: Integer;begin //限制为18位数 if IntValue 8000000000000000000 then begin Result := ‘‘; Exit; end; bi := IntToStr(IntValue); //格式化为 bi := StringOfChar(‘0‘, 20 - Length(bi)) + bi; //从左侧开始格式化 LastBt := ‘ ‘; LastHit := 0; reach := False; for i := 1 to 20 do begin //如果非0 if (bi[i] >= ‘1‘) and (bi[i] <= ‘9‘) then begin //如果前一位是0,又不到分界位,补零 if reach and (LastBt = ‘0‘) and (i mod 4 1) then begin rs := rs + DP[1]; end; reach := True; //转换数字,如果是十位,且前一位为0 if SoftTone and (i mod 4 = 3) and (LastBt = ‘0‘) and ((not reach) or (bi[i] = ‘1‘)) then else begin rs := rs + DP[(Ord(bi[i]) - Ord(‘0‘)) mod 10 + 1]; end; //添加位名 n := (20 - i) mod 20 + 1; if n > 1 then begin rs := rs + DN[n]; end; LastHit := 20 - i; end; //分界名 if (bi[i] = ‘0‘) and (i mod 4 = 0) and reach then begin //特殊分界处的显示原则,8位前为空的不显示分界名 //不是8位处的,4位前为空不显示分界名 n := (20 - i) mod 20 + 1; t := n - 1; if (n > 1) and ( ((t mod 8 = 0) and (LastHit - t < 8)) or (((t - 12) mod 8 = 0) and (LastHit - t = 0 then if Result = ‘‘ then Result := FAlias.Values[Ws[i]] else Result := Result + ‘,‘ + FAlias.Values[Ws[i]] else if Result = ‘‘ then Result := Ws[i] else Result := Result + Ws[i]; end;end;function TCnDigits.StrToAlias2(S: String): String;var Ws: WideString; i: Integer; t: Integer;begin Ws := S; for i := 1 to Length(Ws) do begin t := TStringList(FAlias).IndexOfName(Ws[i]); if t >= 0 then Result := Result + FAlias.Values[Ws[i]] else Result := Result + Ws[i]; end;end;constructor TCnDigits.Create(AOwner: TComponent);begin inherited; FAlias := TStringList.Create; TStringList(FAlias).Sorted := True; TStringList(FAlias).Duplicates := dupIgnore;end;destructor TCnDigits.Destroy;begin FAlias.Free; inherited;end;procedure TCnDigits.SetDA(const Value: Boolean);var Ws: WideString; i: Integer; sv: String;begin if Value then begin Ws := DP + DN + CrNa + DtNa; for i := 1 to Length(Ws) do begin sv := Ws[i]; FAlias.Add(sv + ‘=‘ + FAlias.Values[Ws[i]]); end; end else begin for i := FAlias.Count - 1 downto 0 do begin sv := FAlias[i]; if Trim(sv) = ‘‘ then FAlias.Delete(i) else if (Length(sv) > 0) and (sv[Length(sv)] = ‘=‘) then FAlias.Delete(i); end; end; Fda := Value;end;procedure TCnDigits.SetCnUP(const Value: String);begin //FCnUpDigits := Value;end;class function TCnDigits.StdFmtDate(AValue: TDate; DigitsYear: Boolean): String;var yy, mm, dd: Word; ys: WideString; rs: WideString;begin DecodeDate(AValue, yy, mm, dd); if DigitsYear then ys := LzhFmtDigits(IntToStr(yy)) + DtNa[1] else ys := LzhFmtInt(yy, True) + DtNa[1]; rs := ys; if (mm <= 2) or (mm = 10) then rs := rs + DP[1]; rs := rs + LzhFmtInt(mm) + DtNa[2]; if (dd < 10) or (dd mod 10 = 0) then rs := rs + DP[1]; rs := rs + LzhFmtInt(dd) + DtNa[3]; Result := rs;end;class function TCnDigits.StdFmtDateTime(AValue: TDateTime; DigitsYear: Boolean): String;var dt: TDate; tm: TTime;begin dt := AValue; tm := AValue; Result := StdFmtDate(dt, DigitsYear) + LzhFmtTime(tm);end;end.附例子Demo

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值