Java 实现海康摄像头抓拍图片
本人遇到的问题描述:我的电脑是64位系统,32位jdk,刚开始下载了64位的SDK,一直报 :Unable to load library 'HCNetSDK': ÕҲ»µ½ָ¶¨ 这种错,后来更换了32位的 SDK,成功,所以应该和 jdk 版本有关系和电脑系统没关系。
引入:log4j-1.2.16.jar,quartz-2.2.1.jar,slf4j-api-1.6.6.jar,slf4j-log4j12-1.6.6.jar
将 SDK 中的库文件全部放到 src 文件夹下,引入 SDK 中的两个 jar:examples.jar,jna.jar
import java.io.File; import java.io.UnsupportedEncodingException; public class HCNetSDKPath { public static String DLL_PATH; static{ String path=(HCNetSDKPath.class.getResource("/").getPath()).replaceAll("%20", " ").substring(1).replace("/", "\\"); try { DLL_PATH= java.net.URLDecoder.decode(path,"utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }
更改 HCNetSDK.java:
将:HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("../lib/HCNetSDK", HCNetSDK.class);
改为:HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(HCNetSDKPath.DLL_PATH+"HCNetSDK.dll", HCNetSDK.class);
将:boolean NET_DVR_CaptureJPEGPicture_NEW(NativeLong lUserID, NativeLong lChannel, NET_DVR_JPEGPARA lpJpegPara, String sJpegPicBuffer, int dwPicSize, IntByReference lpSizeReturned);
改为:boolean NET_DVR_CaptureJPEGPicture_NEW(NativeLong lUserID, NativeLong lChannel, NET_DVR_JPEGPARA lpJpegPara, ByteBuffer sJpegPicBuffer, int dwPicSize, IntByReference lpSizeReturned);
import com.sun.jna.NativeLong; public class MonitorCameraInfo { String CameraIp; int CameraPort; String UserName; String UserPwd; NativeLong UserId; NativeLong Channel; public String getCameraIp() { return CameraIp; } public int getCameraPort() { return CameraPort; } public String getUserName() { return UserName; } public String getUserPwd() { return UserPwd; } public NativeLong getUserId() { return UserId; } public NativeLong getChannel() { return Channel; } public void setCameraIp(String cameraIp) { CameraIp = cameraIp; } public void setCameraPort(int cameraPort) { CameraPort = cameraPort; } public void setUserName(String userName) { UserName = userName; } public void setUserPwd(String userPwd) { UserPwd = userPwd; } public void setUserId(NativeLong userId) { UserId = userId; } public void setChannel(NativeLong channel) { Channel = channel; } }
import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sxtb.ai.HCNetSDK.NET_DVR_DEVICEINFO_V30; import com.sxtb.ai.HCNetSDK.NET_DVR_IPPARACFG; import com.sxtb.ai.HCNetSDK.NET_DVR_JPEGPARA; import com.sxtb.ai.HCNetSDK.NET_DVR_WORKSTATE_V30; public class TestQuartz implements Job { public void execute(JobExecutionContext arg0) throws JobExecutionException { TestQuartz tqQuartz = new TestQuartz(); try { tqQuartz.getImages(); } catch (IOException e) { e.printStackTrace(); } } public void getImages() throws IOException{ final TestQuartz app = new TestQuartz(); final MonitorCameraInfo cameraInfo = new MonitorCameraInfo(); cameraInfo.setCameraIp("192.168.1.64"); cameraInfo.setCameraPort(8000); cameraInfo.setUserName("admin"); cameraInfo.setUserPwd("admin@123"); app.getDVRConfig(cameraInfo); app.getDVRPic(cameraInfo); } public void getDVRConfig(MonitorCameraInfo cameraInfo) { HCNetSDK sdk = HCNetSDK.INSTANCE; //判断摄像头是否开启 if (!sdk.NET_DVR_Init()) { System.out.println("SDK初始化失败"); return; } NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息 //登录信息 NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(), cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo); cameraInfo.setUserId(id);// 返回一个用户编号,同时将设备信息写入devinfo if (cameraInfo.getUserId().intValue() < 0) { System.out.println("设备注册失败"); return; } //DVR工作状态 NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30(); if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) { // 返回Boolean值,判断是否获取设备能力 System.out.println("返回设备状态失败"); } IntByReference ibrBytesReturned = new IntByReference(0);// 获取IP接入配置参数 NET_DVR_IPPARACFG ipcfg = new NET_DVR_IPPARACFG();//IP接入配置结构 ipcfg.write(); Pointer lpIpParaConfig = ipcfg.getPointer(); //获取相关参数配置 sdk.NET_DVR_GetDVRConfig(cameraInfo.getUserId(), HCNetSDK.NET_DVR_GET_IPPARACFG, new NativeLong(0), lpIpParaConfig, ipcfg.size(), ibrBytesReturned); ipcfg.read(); System.out.print("IP地址:" + cameraInfo.getCameraIp()); System.out.println("|设备状态:" + devwork.dwDeviceStatic);// 0正常,1CPU占用率过高,2硬件错误,3未知 //System.out.println("ChanNum"+devinfo.byChanNum); // 显示模拟通道 for (int i = 0; i < devinfo.byChanNum; i++) { System.out.print("Camera" + i + 1);// 模拟通道号名称 System.out.print("|是否录像:" + devwork.struChanStatic[i].byRecordStatic);// 0不录像,不录像 System.out.print("|信号状态:" + devwork.struChanStatic[i].bySignalStatic);// 0正常,1信号丢失 System.out.println("|硬件状态:" + devwork.struChanStatic[i].byHardwareStatic);// 0正常,1异常 } //注销用户 sdk.NET_DVR_Logout(cameraInfo.getUserId());//释放SDK资源 sdk.NET_DVR_Cleanup(); } //抓拍图片 public void getDVRPic(MonitorCameraInfo cameraInfo) throws IOException { //设置通道号,其中1正常,-1不正常 NativeLong chanLong = new NativeLong(1); cameraInfo.setChannel(chanLong); //System.out.println("Channel:"+chanLong); long startTime = System.currentTimeMillis(); HCNetSDK sdk = HCNetSDK.INSTANCE; if (!sdk.NET_DVR_Init()) { System.out.println("SDK初始化失败"); return; } NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息 //注册设备 NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(), cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo); cameraInfo.setUserId(id);// 返回一个用户编号,同时将设备信息写入devinfo if (cameraInfo.getUserId().intValue() < 0) { System.out.println("设备注册失败"+sdk.NET_DVR_GetLastError()); return; } else { System.out.println("id:" + cameraInfo.getUserId().intValue()); } NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30(); if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) { // 返回Boolean值,判断是否获取设备能力 System.out.println("返回设备状态失败"); } //System.out.println("设备注册耗时:[" + (System.currentTimeMillis() - startTime) + "]"); startTime = System.currentTimeMillis(); //图片质量 NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA(); // 设置图片的分辨率 jpeg.wPicSize = 2; // 设置图片质量 jpeg.wPicQuality = 2; IntByReference a = new IntByReference(); //设置图片大小 ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024); // 创建文件目录和文件 SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd"); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); Date date = new Date(); //按照每天设置一个目录 String fileName = "D:/CapturePicture/" + sd.format(date); File files = new File(fileName); if(!files.exists()){ files.mkdirs(); } //按照日期文件夹放入图片 String fileNameString = fileName+"/"+sdf.format(date)+".jpg"; System.out.println("抓拍图片存储路径:" + fileNameString); File file = new File(fileNameString); // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中 //需要加入通道 boolean is = sdk.NET_DVR_CaptureJPEGPicture_NEW(cameraInfo.getUserId(), cameraInfo.getChannel(), jpeg, jpegBuffer, 1024 * 1024, a); //System.out.println("Channel:"+cameraInfo.getChannel()); System.out.println("抓图到内存耗时:[" + (System.currentTimeMillis() - startTime) + "ms]"); // 抓图到文件 //boolean is = sdk.NET_DVR_CaptureJPEGPicture(cameraInfo.UserId,cameraInfo.Channel,jpeg, fileNameString); if (is) { System.out.println("抓取成功,返回长度:" + a.getValue()); } else { System.out.println("抓取失败:"+sdk.NET_DVR_GetLastError()); } //startTime = System.currentTimeMillis(); // 存储本地,写入内容 BufferedOutputStream outputStream = null; try { outputStream = new BufferedOutputStream(new FileOutputStream(file)); outputStream.write(jpegBuffer.array(), 0, a.getValue()); outputStream.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("存储本地耗时:[" + (System.currentTimeMillis() - startTime) + "ms]"); sdk.NET_DVR_Logout(cameraInfo.getUserId()); sdk.NET_DVR_Cleanup(); } }
import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; /** * 创建调度任务并执行 * */ public class MainScheduler { @SuppressWarnings("unused") public static void main(String[] args) throws Exception { MainScheduler mainScheduler = new MainScheduler(); MainScheduler.schedulerJob(); } //创建调度器 public static Scheduler getScheduler() throws Exception{ SchedulerFactory schedulerFactory = new StdSchedulerFactory(); return schedulerFactory.getScheduler(); } public static void schedulerJob() throws Exception{ //创建任务 JobDetail jobDetail = JobBuilder.newJob(TestQuartz.class).withIdentity("job1", "group1").build(); //创建触发器,每5s执行一次,如果是分钟,则把withIntervalInSeconds(intervalInSeconds)改成withIntervalInMinutes(intervalInMinutes) Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group3").withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()).build(); Scheduler scheduler = getScheduler(); //将任务及其触发器放入调度器 scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }
log4j.properties 文件: log4j.rootLogger=CONSOLE,FILE log4j.addivity.org.apache=true # \u5E94\u7528\u4E8E\u63A7\u5236\u53F0 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Threshold=INFO log4j.appender.CONSOLE.Target=System.out log4j.appender.CONSOLE.Encoding=GBK log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n # \u6BCF\u5929\u65B0\u5EFA\u65E5\u5FD7 log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender log4j.appender.A1.File=D:/log4j/log log4j.appender.A1.Encoding=GBK log4j.appender.A1.Threshold=DEBUG log4j.appender.A1.DatePattern='.'yyyy-MM-dd log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L : %m%n #\u5E94\u7528\u4E8E\u6587\u4EF6 log4j.appender.FILE=org.apache.log4j.FileAppender log4j.appender.FILE.File=D:/log4j/file.log log4j.appender.FILE.Append=false log4j.appender.FILE.Encoding=GBK log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n # \u5E94\u7528\u4E8E\u6587\u4EF6\u56DE\u6EDA log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender log4j.appender.ROLLING_FILE.Threshold=ERROR log4j.appender.ROLLING_FILE.File=rolling.log log4j.appender.ROLLING_FILE.Append=true log4j.appender.CONSOLE_FILE.Encoding=GBK log4j.appender.ROLLING_FILE.MaxFileSize=10KB log4j.appender.ROLLING_FILE.MaxBackupIndex=1 log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n #\u81EA\u5B9A\u4E49Appender log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender log4j.appender.im.host = mail.cybercorlin.net log4j.appender.im.username = username log4j.appender.im.password = password log4j.appender.im.recipient = yyflyons@163.com log4j.appender.im.layout=org.apache.log4j.PatternLayout log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n #\u5E94\u7528\u4E8Esocket log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender log4j.appender.SOCKET.RemoteHost=localhost log4j.appender.SOCKET.Port=5001 log4j.appender.SOCKET.LocationInfo=true # Set up for Log Facter 5 log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n # Log Factor 5 Appender log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000 # \u53D1\u9001\u65E5\u5FD7\u7ED9\u90AE\u4EF6 log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender log4j.appender.MAIL.Threshold=FATAL log4j.appender.MAIL.BufferSize=10 log4j.appender.MAIL.From=yyflyons@163.com log4j.appender.MAIL.SMTPHost=www.wusetu.com log4j.appender.MAIL.Subject=Log4J Message log4j.appender.MAIL.To=yyflyons@126.com log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n