|
|
|
@ -35,8 +35,6 @@ import org.apache.commons.compress.utils.IOUtils; |
|
|
|
import org.apache.commons.csv.CSVFormat; |
|
|
|
import org.apache.commons.csv.CSVParser; |
|
|
|
import org.apache.commons.csv.CSVRecord; |
|
|
|
import org.apache.commons.net.ftp.FTP; |
|
|
|
import org.apache.commons.net.ftp.FTPClient; |
|
|
|
import org.apache.commons.net.ftp.FTPSClient; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
@ -51,8 +49,6 @@ import java.awt.image.BufferedImage; |
|
|
|
import java.io.*; |
|
|
|
import java.net.URI; |
|
|
|
import java.net.URISyntaxException; |
|
|
|
import java.nio.ByteBuffer; |
|
|
|
import java.nio.ByteOrder; |
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
import java.nio.file.Files; |
|
|
|
import java.nio.file.Path; |
|
|
|
@ -78,9 +74,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
private HCNetSDK hcNetSDK; |
|
|
|
|
|
|
|
private static HikFExceptionCallBack_Imp fExceptionCallBack; |
|
|
|
// |
|
|
|
// @Resource |
|
|
|
// private DjService djService; |
|
|
|
|
|
|
|
|
|
|
|
private String picPath; |
|
|
|
|
|
|
|
@ -124,6 +118,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
|
|
|
|
@Resource |
|
|
|
private RedisService redisService; |
|
|
|
|
|
|
|
@Override |
|
|
|
public AjaxResult login(NvrInfo nvrInfo) { |
|
|
|
return login_V40(nvrInfo); |
|
|
|
@ -146,7 +141,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
System.out.println(":设备登录成功!" + lUserID); |
|
|
|
// birdNvrMapper.updateNvrInfo(nvrInfo); |
|
|
|
// redisTemplate.opsForValue().set(nvrInfo.getNvrIp() + "_userId", lUserID); |
|
|
|
redisService. setCacheObject(nvrInfo.getNvrIp()+ "_userId", lUserID); |
|
|
|
redisService.setCacheObject(nvrInfo.getNvrIp() + "_userId", lUserID); |
|
|
|
//若果设备序列号为空时,即为第一次登陆,写入基础数据 |
|
|
|
if (nvrInfo.getNvrSerial() == null || nvrInfo.getNvrSerial().equals("")) { |
|
|
|
m_strDeviceInfo.read(); |
|
|
|
@ -302,7 +297,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
|
|
|
|
@Override |
|
|
|
public AjaxResult cameraAngleJump(Camera camera) { |
|
|
|
log.info(camera.getIp()+"摄像头跳转"); |
|
|
|
log.info(camera.getIp() + "摄像头跳转"); |
|
|
|
// hcNetSDK.NET_DVR_Init(); |
|
|
|
// 1. 登录设备 |
|
|
|
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = HikVisionUtils.login_V40( |
|
|
|
@ -330,7 +325,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
log.error("获取设备预置位跳转设备参数失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); |
|
|
|
return AjaxResult.error(hcNetSDK.NET_DVR_GetErrorMsg(new IntByReference(hcNetSDK.NET_DVR_GetLastError()))); |
|
|
|
} else { |
|
|
|
log.info("海康-成功跳转到预置位!"+camera.getPointNum()); |
|
|
|
log.info("海康-成功跳转到预置位!" + camera.getPointNum()); |
|
|
|
} |
|
|
|
return AjaxResult.success(); |
|
|
|
} |
|
|
|
@ -339,7 +334,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
//抓图 |
|
|
|
@Override |
|
|
|
public Camera cameraPictrue(Camera camera) throws Exception { |
|
|
|
log.info(camera.getIp()+"摄像头抓图"); |
|
|
|
log.info(camera.getIp() + "摄像头抓图"); |
|
|
|
if (camera.getLUserID() != 0) { |
|
|
|
// 1. 登录设备 |
|
|
|
HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = HikVisionUtils.login_V40( |
|
|
|
@ -419,7 +414,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
|
|
|
|
//1:跳转预置位 |
|
|
|
//家里相机没有预置位,现场相机存在预置位需要跳转到画测温框预置位,否则无法获取规则温度 |
|
|
|
cameraAngleJump(camera); |
|
|
|
cameraAngleJump(camera); |
|
|
|
|
|
|
|
//2:抓取图片,保存到ftp |
|
|
|
try { |
|
|
|
@ -722,150 +717,6 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//相机红外图谱获取 |
|
|
|
public InfraredInfo readDataHw(byte[] bytes, Coordinate coordinate) throws IOException { |
|
|
|
|
|
|
|
InfraredInfo infraredInfo = new InfraredInfo(); |
|
|
|
byte[] infraredData = locateAndReadInfraredData(bytes); |
|
|
|
if (infraredData != null) { |
|
|
|
System.out.println("成功读取红外数据,长度: " + infraredData.length + " 字节"); |
|
|
|
|
|
|
|
ByteBuffer buffer = ByteBuffer.wrap(infraredData).order(ByteOrder.LITTLE_ENDIAN); |
|
|
|
|
|
|
|
// 1. 读取文件元数据 |
|
|
|
short fileVersion = buffer.getShort(); |
|
|
|
infraredInfo.setFileVersion(Short.toString(fileVersion)); |
|
|
|
|
|
|
|
//矩阵宽度 |
|
|
|
short width = buffer.getShort(); |
|
|
|
infraredInfo.setMatrixWidth(width); |
|
|
|
|
|
|
|
//矩阵高度 |
|
|
|
short height = buffer.getShort(); |
|
|
|
infraredInfo.setMatrixHeight(height); |
|
|
|
|
|
|
|
//拍摄时间 |
|
|
|
byte[] timeBytes = new byte[14]; |
|
|
|
buffer.get(timeBytes); |
|
|
|
String captureTime = new String(timeBytes, StandardCharsets.US_ASCII); |
|
|
|
infraredInfo.setCaptureTime(captureTime); |
|
|
|
|
|
|
|
// 2. 读取温度矩阵数据 |
|
|
|
float[][] temperatureMatrix = new float[height][width]; |
|
|
|
for (int row = 0; row < height; row++) { |
|
|
|
for (int col = 0; col < width; col++) { |
|
|
|
temperatureMatrix[row][col] = buffer.getFloat(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
infraredInfo.setTemperatureMatrix(temperatureMatrix); |
|
|
|
float maxTemp = Float.MIN_VALUE; |
|
|
|
float minTemp = Float.MAX_VALUE; |
|
|
|
|
|
|
|
for (float[] row : temperatureMatrix) { |
|
|
|
for (float temp : row) { |
|
|
|
maxTemp = Math.max(maxTemp, temp); |
|
|
|
minTemp = Math.min(minTemp, temp); |
|
|
|
} |
|
|
|
} |
|
|
|
//最大最小温度值 |
|
|
|
infraredInfo.setMaxTemp(maxTemp); |
|
|
|
infraredInfo.setMinTemp(minTemp); |
|
|
|
// 3. 解析保留的数据(环境参数等) |
|
|
|
if (buffer.remaining() >= 18) { // 至少需要18字节(4+4+1+4+1+4) |
|
|
|
// 3.1 辐射率 (4字节 float) |
|
|
|
float emissivity = buffer.getFloat(); |
|
|
|
infraredInfo.setEmissivity(Math.min(1.0f, Math.max(0.0f, emissivity))); |
|
|
|
|
|
|
|
// 3.2 环境温度 (4字节 float ℃) |
|
|
|
float ambientTemp = buffer.getFloat(); |
|
|
|
infraredInfo.setAmbientTemp(ambientTemp); |
|
|
|
|
|
|
|
// 3.3 镜头度数 (1字节 byte) |
|
|
|
byte lensDegree = buffer.get(); |
|
|
|
infraredInfo.setLensDegree(lensDegree); |
|
|
|
|
|
|
|
// 3.4 拍摄距离 (4字节 float 米) |
|
|
|
long distance = buffer.getInt() & 0xFFFFFFFFL; |
|
|
|
infraredInfo.setDistance(distance); |
|
|
|
|
|
|
|
// 3.5 相对湿度 (1字节 byte %) |
|
|
|
byte humidity = buffer.get(); |
|
|
|
infraredInfo.setHumidity(humidity); |
|
|
|
|
|
|
|
// 3.6 反射温度 (4字节 float ℃) |
|
|
|
float reflectedTemp = buffer.getFloat(); |
|
|
|
infraredInfo.setReflectedTemp(reflectedTemp); |
|
|
|
|
|
|
|
//生产厂家 |
|
|
|
byte[] productor = new byte[32]; |
|
|
|
buffer.get(productor); |
|
|
|
String productorStr = new String(productor, StandardCharsets.US_ASCII).trim(); |
|
|
|
infraredInfo.setProductor(productorStr); |
|
|
|
|
|
|
|
//产品型号 |
|
|
|
byte[] typeBytes = new byte[32]; |
|
|
|
buffer.get(typeBytes); |
|
|
|
String typeStr = new String(typeBytes, StandardCharsets.US_ASCII).trim(); |
|
|
|
infraredInfo.setTypeStr(typeStr); |
|
|
|
|
|
|
|
//产品序列号 |
|
|
|
byte[] serialNo = new byte[32]; |
|
|
|
buffer.get(serialNo); |
|
|
|
String serialNoStr = new String(serialNo, StandardCharsets.US_ASCII).trim(); |
|
|
|
infraredInfo.setSerialNo(serialNoStr); |
|
|
|
|
|
|
|
// // 检查是否有额外数据 |
|
|
|
// if (buffer.hasRemaining()) |
|
|
|
// |
|
|
|
// { |
|
|
|
// System.out.println("警告:还有 " + buffer.remaining() + " 字节未解析数据"); |
|
|
|
// System.out.print("剩余数据: "); |
|
|
|
// for (int i = 0; i < Math.min(16, buffer.remaining()); i++) { |
|
|
|
// System.out.printf("%02x ", buffer.get()); |
|
|
|
// } |
|
|
|
// System.out.println(); |
|
|
|
// } |
|
|
|
//绘制框选标识 |
|
|
|
if (coordinate != null) { |
|
|
|
//String s = ImageOverlaysNvr(coordinate, infraredInfo); |
|
|
|
//infraredInfo.setOutPath(s); |
|
|
|
} |
|
|
|
} else { |
|
|
|
System.err.println("错误:剩余数据不足以解析环境参数"); |
|
|
|
} |
|
|
|
} else { |
|
|
|
System.out.println("读取失败"); |
|
|
|
} |
|
|
|
return infraredInfo; |
|
|
|
} |
|
|
|
|
|
|
|
//点测温 |
|
|
|
// public InfraredInfo PointTemperatureShow(Coordinate coordinate, short width, short height, float[][] temperatureMatrix) { |
|
|
|
// InfraredInfo infraredInfo = new InfraredInfo(); |
|
|
|
// // 获取指定坐标的温度 |
|
|
|
// if (ObjectUtil.isNotEmpty(coordinate.getFirstX())) { |
|
|
|
// if (coordinate.getImgType() != 3) {//无人机不需要对比底图 |
|
|
|
// //比例缩放像素 获取底图温度值 |
|
|
|
// double xMultiple = (coordinate.getImgWidth().doubleValue() / width) * 100 / 100.0; |
|
|
|
// double yMultiple = (coordinate.getImgHeight().doubleValue() / height) * 100 / 100.0; |
|
|
|
// |
|
|
|
// int x = (int) (coordinate.getFirstX() / xMultiple); |
|
|
|
// int y = (int) (coordinate.getFirstY() / yMultiple); |
|
|
|
// coordinate.setFirstX(x); |
|
|
|
// coordinate.setFirstY(y); |
|
|
|
// } |
|
|
|
// |
|
|
|
// if (coordinate.getFirstX() >= 0 && coordinate.getFirstX() <= width && coordinate.getFirstY() >= 0 && coordinate.getFirstY() <= height) { |
|
|
|
// float pointTemperature = temperatureMatrix[coordinate.getFirstY()][coordinate.getFirstX()]; // 注意:y是行,x是列 |
|
|
|
// infraredInfo.setPointTemperature(pointTemperature); |
|
|
|
// } else { |
|
|
|
// System.err.println("错误:坐标超出范围"); |
|
|
|
// } |
|
|
|
// } |
|
|
|
// return infraredInfo; |
|
|
|
// } |
|
|
|
|
|
|
|
//框选温度值计算 |
|
|
|
public InfraredInfo matrixTemperatureShow(Coordinate coordinate, short width, short height, float[][] temperatureMatrix) { |
|
|
|
InfraredInfo infraredInfo = new InfraredInfo(); |
|
|
|
@ -927,328 +778,6 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
return infraredInfo; |
|
|
|
} |
|
|
|
|
|
|
|
//校验 |
|
|
|
public static byte[] locateAndReadInfraredData(byte[] fileData) { |
|
|
|
// 文件末尾标识 |
|
|
|
final byte[] FOOTER_SIGN = { |
|
|
|
(byte) 0x37, (byte) 0x66, (byte) 0x07, (byte) 0x1a, |
|
|
|
(byte) 0x12, (byte) 0x3a, (byte) 0x4c, (byte) 0x9f, |
|
|
|
(byte) 0xa9, (byte) 0x5d, (byte) 0x21, (byte) 0xd2, |
|
|
|
(byte) 0xda, (byte) 0x7d, (byte) 0x26, (byte) 0xbc |
|
|
|
}; |
|
|
|
|
|
|
|
try { |
|
|
|
// 1. 检查数据大小 |
|
|
|
if (fileData.length < FOOTER_SIGN.length + 4) { |
|
|
|
System.err.println("错误:数据太小"); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
// 2. 读取并验证文件尾标识 |
|
|
|
byte[] footer = new byte[FOOTER_SIGN.length]; |
|
|
|
// 从数组末尾读取FOOTER_SIGN |
|
|
|
System.arraycopy(fileData, fileData.length - FOOTER_SIGN.length, footer, 0, FOOTER_SIGN.length); |
|
|
|
|
|
|
|
if (!Arrays.equals(footer, FOOTER_SIGN)) { |
|
|
|
System.err.println("错误:文件标识不匹配"); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
// 3. 读取偏移量(小端序) |
|
|
|
byte[] offsetBytes = new byte[4]; |
|
|
|
// 读取FOOTER_SIGN前的4个字节作为偏移量 |
|
|
|
System.arraycopy(fileData, fileData.length - FOOTER_SIGN.length - 4, offsetBytes, 0, 4); |
|
|
|
int dataOffset = ByteBuffer.wrap(offsetBytes) |
|
|
|
.order(ByteOrder.LITTLE_ENDIAN) |
|
|
|
.getInt(); |
|
|
|
|
|
|
|
// 4. 验证偏移量有效性 |
|
|
|
if (dataOffset < 0 || dataOffset >= fileData.length - FOOTER_SIGN.length - 4) { |
|
|
|
System.err.println("错误:无效的偏移量"); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
// 5. 定位到偏移量处读取数据(直到文件尾标识前) |
|
|
|
int dataLength = fileData.length - FOOTER_SIGN.length - 4 - dataOffset; |
|
|
|
if (dataLength <= 0) { |
|
|
|
System.err.println("错误:数据长度为0"); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
byte[] infraredData = new byte[dataLength]; |
|
|
|
System.arraycopy(fileData, dataOffset, infraredData, 0, dataLength); |
|
|
|
|
|
|
|
return infraredData; |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
System.err.println("处理错误: " + e.getMessage()); |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//图片标注__无人机/ivs1800/nvr |
|
|
|
public String ImageOverlays(InfraPictureInfo infraPictureInfo, InfraredInfo infraredInfo) { |
|
|
|
|
|
|
|
List<Coordinate> coordinates = infraPictureInfo.getCoordinates(); |
|
|
|
|
|
|
|
Date date = new Date(); |
|
|
|
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); |
|
|
|
String markPicName = sf.format(date); |
|
|
|
// 图片路径(请替换为实际路径) |
|
|
|
String imagePath = infraPictureInfo.getFilePath(); |
|
|
|
// 获取文件名(不含扩展名) |
|
|
|
File file = new File(imagePath); |
|
|
|
String fileName = file.getName(); |
|
|
|
String pureName = fileName.substring(0, fileName.lastIndexOf('.')); |
|
|
|
String filename = picPath; |
|
|
|
String outputPath = picPath + pureName + "_" + markPicName + ".jpg"; |
|
|
|
//判断路径是否存在 |
|
|
|
File filePath = new File(filename); |
|
|
|
if (!filePath.exists()) { |
|
|
|
//不存在,创建目录 |
|
|
|
filePath.mkdirs(); |
|
|
|
} |
|
|
|
try { |
|
|
|
InputStream inputStreamPath = downloadFtp(imagePath); |
|
|
|
if (inputStreamPath == null) { |
|
|
|
System.out.println("无法加载图片: " + imagePath); |
|
|
|
return null; |
|
|
|
} |
|
|
|
// 加载原始图片 |
|
|
|
BufferedImage originalImage = ImageIO.read(inputStreamPath); |
|
|
|
// 创建可编辑的图片副本 |
|
|
|
BufferedImage annotatedImage = new BufferedImage( |
|
|
|
originalImage.getWidth(), |
|
|
|
originalImage.getHeight(), |
|
|
|
BufferedImage.TYPE_INT_RGB |
|
|
|
); |
|
|
|
// 绘制原始图片 |
|
|
|
Graphics2D g2d = annotatedImage.createGraphics(); |
|
|
|
g2d.drawImage(originalImage, 0, 0, null); |
|
|
|
// 设置标注样式 |
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
|
|
|
// Font font = new Font("微软雅黑", Font.BOLD, 17); |
|
|
|
Font font = new Font("WenQuanYi Zen Hei", Font.BOLD, 20); |
|
|
|
final String imageType = infraPictureInfo.getImgType(); |
|
|
|
if (AlgConstants.INFRA_YU3.equals(imageType)) { |
|
|
|
for (Coordinate c : coordinates) { |
|
|
|
//点标注 |
|
|
|
if (c.getFirstX() != null && c.getFirstY() != null && c.getSecondX() == null && c.getSecondY() == null) { |
|
|
|
g2d.setFont(font); |
|
|
|
// 标注点坐标 |
|
|
|
g2d.setColor(Color.WHITE); |
|
|
|
int x = c.getFirstX(); |
|
|
|
int y = c.getFirstY(); |
|
|
|
|
|
|
|
// 确保坐标在图片范围内 |
|
|
|
if (x >= 0 && x < originalImage.getWidth() && |
|
|
|
y >= 0 && y < originalImage.getHeight()) { |
|
|
|
// 绘制点(用实心圆表示) |
|
|
|
g2d.fillOval(x - 3, y - 3, 6, 6); |
|
|
|
infraPictureInfo.setFirstX(x); |
|
|
|
infraPictureInfo.setFirstY(y); |
|
|
|
// InfraredInfo drawStringPoint = PointTemperatureShow(c, infraredInfo.getMatrixWidth(), infraredInfo.getMatrixHeight(), infraredInfo.getTemperatureMatrix()); |
|
|
|
// // 添加坐标标签 |
|
|
|
// g2d.drawString("(" + String.format("%.2f", drawStringPoint.getPointTemperature()) + ")", x + 8, y - 8); |
|
|
|
} |
|
|
|
} |
|
|
|
//矩阵标注 |
|
|
|
if (c.getSecondX() != null && c.getSecondY() != null) { |
|
|
|
// 标注矩形(每两个点确定一个矩形) |
|
|
|
g2d.setColor(Color.WHITE); |
|
|
|
int x1 = c.getFirstX(); |
|
|
|
int y1 = c.getFirstY(); |
|
|
|
int x2 = c.getSecondX(); |
|
|
|
int y2 = c.getSecondY(); |
|
|
|
|
|
|
|
// 确保坐标在图片范围内 |
|
|
|
if (x1 >= 0 && x1 < originalImage.getWidth() && y1 >= 0 && y1 < originalImage.getHeight() && |
|
|
|
x2 >= 0 && x2 < originalImage.getWidth() && y2 >= 0 && y2 < originalImage.getHeight()) { |
|
|
|
|
|
|
|
// 确保x1,y1是左上角,x2,y2是右下角 |
|
|
|
int rectX = Math.min(x1, x2); |
|
|
|
int rectY = Math.min(y1, y2); |
|
|
|
int width = Math.abs(x2 - x1); |
|
|
|
int height = Math.abs(y2 - y1); |
|
|
|
|
|
|
|
// 设置更粗的画笔(加粗矩形边框) |
|
|
|
g2d.setStroke(new BasicStroke(3)); // 3像素宽 |
|
|
|
// 绘制矩形 |
|
|
|
g2d.drawRect(rectX, rectY, width, height); |
|
|
|
infraPictureInfo.setFirstX(x1); |
|
|
|
infraPictureInfo.setFirstY(y1); |
|
|
|
infraPictureInfo.setSecondX(x2); |
|
|
|
infraPictureInfo.setSecondY(y2); |
|
|
|
|
|
|
|
InfraredInfo drawStringMatrix = matrixTemperatureShow(c, infraredInfo.getMatrixWidth(), infraredInfo.getMatrixHeight(), infraredInfo.getTemperatureMatrix()); |
|
|
|
infraredInfo.setFrameMax(Math.round(drawStringMatrix.getFrameMax() * 100) / 100f); |
|
|
|
Integer maxTempX = drawStringMatrix.getMaxTempX(); |
|
|
|
Integer maxTempY = drawStringMatrix.getMaxTempY(); |
|
|
|
log.info("最高温度值坐标点:" + "maxTempX:" + maxTempX + " maxTempY:" + maxTempY); |
|
|
|
|
|
|
|
|
|
|
|
// 添加矩形标签 |
|
|
|
String line1 = "平均温度:" + String.format("%.2f", drawStringMatrix.getFrameAverage()); |
|
|
|
String line2 = "最高温度:" + String.format("%.2f", drawStringMatrix.getFrameMax()); |
|
|
|
String line3 = "最低温度:" + String.format("%.2f", drawStringMatrix.getFrameMin()); |
|
|
|
g2d.drawString(line1, rectX + 5, rectY + 15); |
|
|
|
g2d.drawString(line2, rectX + 5, rectY + 30); |
|
|
|
g2d.drawString(line3, rectX + 5, rectY + 45); |
|
|
|
|
|
|
|
// 在最高温度点画一个空心圆(红色边框) |
|
|
|
if (maxTempX != null && maxTempY != null) { |
|
|
|
log.info("画最高温度的点,坐标:x={}, y={}", maxTempX, maxTempY); |
|
|
|
|
|
|
|
// 边界检查 |
|
|
|
if (maxTempX >= 0 && maxTempX < originalImage.getWidth() && |
|
|
|
maxTempY >= 0 && maxTempY < originalImage.getHeight()) { |
|
|
|
|
|
|
|
// 设置醒目的颜色 |
|
|
|
g2d.setColor(Color.RED); |
|
|
|
g2d.setStroke(new BasicStroke(5)); |
|
|
|
|
|
|
|
// 画空心圆 |
|
|
|
int circleDiameter = 8; |
|
|
|
g2d.drawOval(maxTempX - circleDiameter / 2, maxTempY - circleDiameter / 2, |
|
|
|
circleDiameter, circleDiameter); |
|
|
|
|
|
|
|
// 画十字标记 |
|
|
|
g2d.drawLine(maxTempX - 3, maxTempY, maxTempX + 3, maxTempY); |
|
|
|
g2d.drawLine(maxTempX, maxTempY - 3, maxTempX, maxTempY + 3); |
|
|
|
|
|
|
|
log.info("成功绘制最高温度点标记"); |
|
|
|
} else { |
|
|
|
log.warn("最高温度点坐标超出图像范围:x={}, y={}", maxTempX, maxTempY); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
log.error("画框坐标超出图片范围"); |
|
|
|
// 确保x1,y1是左上角,x2,y2是右下角 |
|
|
|
int rectX = Math.min(1, 639); |
|
|
|
int rectY = Math.min(1, 511); |
|
|
|
int width = Math.abs(639 - 1); |
|
|
|
int height = Math.abs(511 - 1); |
|
|
|
|
|
|
|
// 设置更粗的画笔(加粗矩形边框) |
|
|
|
g2d.setStroke(new BasicStroke(3)); // 3像素宽 |
|
|
|
// 绘制矩形 |
|
|
|
g2d.drawRect(rectX, rectY, width, height); |
|
|
|
infraPictureInfo.setFirstX(x1); |
|
|
|
infraPictureInfo.setFirstY(y1); |
|
|
|
infraPictureInfo.setSecondX(x2); |
|
|
|
infraPictureInfo.setSecondY(y2); |
|
|
|
|
|
|
|
InfraredInfo drawStringMatrix = matrixTemperatureShow(c, infraredInfo.getMatrixWidth(), infraredInfo.getMatrixHeight(), infraredInfo.getTemperatureMatrix()); |
|
|
|
infraredInfo.setFrameMax(Math.round(drawStringMatrix.getFrameMax() * 100) / 100f); |
|
|
|
// 添加矩形标签 |
|
|
|
String line1 = "平均温度:" + String.format("%.2f", drawStringMatrix.getFrameAverage()); |
|
|
|
String line2 = "最高温度:" + String.format("%.2f", drawStringMatrix.getFrameMax()); |
|
|
|
String line3 = "最低温度:" + String.format("%.2f", drawStringMatrix.getFrameMin()); |
|
|
|
g2d.drawString(line1, rectX + 5, rectY + 15); |
|
|
|
g2d.drawString(line2, rectX + 5, rectY + 30); |
|
|
|
g2d.drawString(line3, rectX + 5, rectY + 45); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (AlgConstants.INFRA_1800.equals(imageType)) { |
|
|
|
for (Coordinate c : coordinates) { |
|
|
|
g2d.setFont(font); |
|
|
|
//矩阵标注 |
|
|
|
if (c.getSecondX() != null && c.getSecondY() != null) { |
|
|
|
// 标注矩形(每两个点确定一个矩形) |
|
|
|
g2d.setColor(Color.GREEN); |
|
|
|
int x1 = c.getFirstX(); |
|
|
|
int y1 = c.getFirstY(); |
|
|
|
int x2 = c.getSecondX(); |
|
|
|
int y2 = c.getSecondY(); |
|
|
|
|
|
|
|
// 确保坐标在图片范围内 |
|
|
|
if (x1 >= 0 && x1 < originalImage.getWidth() && y1 >= 0 && y1 < originalImage.getHeight() && |
|
|
|
x2 >= 0 && x2 < originalImage.getWidth() && y2 >= 0 && y2 < originalImage.getHeight()) { |
|
|
|
|
|
|
|
// 确保x1,y1是左上角,x2,y2是右下角 |
|
|
|
int rectX = Math.min(x1, x2); |
|
|
|
int rectY = Math.min(y1, y2); |
|
|
|
int width = Math.abs(x2 - x1); |
|
|
|
int height = Math.abs(y2 - y1); |
|
|
|
// 设置更粗的画笔(加粗矩形边框) |
|
|
|
g2d.setStroke(new BasicStroke(3)); // 3像素宽 |
|
|
|
// 绘制矩形 |
|
|
|
// g2d.drawRect(rectX, rectY, width, height); |
|
|
|
|
|
|
|
infraPictureInfo.setFirstX(x1); |
|
|
|
infraPictureInfo.setFirstY(y1); |
|
|
|
infraPictureInfo.setSecondX(x2); |
|
|
|
infraPictureInfo.setSecondY(y2); |
|
|
|
// 添加矩形标签 |
|
|
|
//图片路径取值 |
|
|
|
String[] dividePath = Paths.get(imagePath).getFileName().toString().replaceAll("(?i)\\.jpg$", "").split("_"); |
|
|
|
String max = dividePath[dividePath.length - 1]; // 最大值 |
|
|
|
infraredInfo.setFrameMax(Float.parseFloat(max)); |
|
|
|
// String line1 = "最高温度:" + max; |
|
|
|
// g2d.drawString(line1, rectX + 5, rectY + 15); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (AlgConstants.INFRA_CAMERA_REVERSE.equals(imageType)) { |
|
|
|
for (Coordinate c : coordinates) { |
|
|
|
g2d.setFont(font); |
|
|
|
//矩阵标注 |
|
|
|
if (c.getSecondX() != null && c.getSecondY() != null) { |
|
|
|
// 标注矩形(每两个点确定一个矩形) |
|
|
|
g2d.setColor(Color.GREEN); |
|
|
|
int x1 = c.getFirstX(); |
|
|
|
int y1 = c.getFirstY(); |
|
|
|
int x2 = c.getSecondX(); |
|
|
|
int y2 = c.getSecondY(); |
|
|
|
|
|
|
|
// 确保坐标在图片范围内 |
|
|
|
if (x1 >= 0 && x1 < originalImage.getWidth() && y1 >= 0 && y1 < originalImage.getHeight() && |
|
|
|
x2 >= 0 && x2 < originalImage.getWidth() && y2 >= 0 && y2 < originalImage.getHeight()) { |
|
|
|
|
|
|
|
// 确保x1,y1是左上角,x2,y2是右下角 |
|
|
|
int rectX = Math.min(x1, x2); |
|
|
|
int rectY = Math.min(y1, y2); |
|
|
|
int width = Math.abs(x2 - x1); |
|
|
|
int height = Math.abs(y2 - y1); |
|
|
|
// 设置更粗的画笔(加粗矩形边框) |
|
|
|
g2d.setStroke(new BasicStroke(3)); // 3像素宽 |
|
|
|
// 绘制矩形 |
|
|
|
g2d.drawRect(rectX, rectY, width, height); |
|
|
|
infraPictureInfo.setFirstX(x1); |
|
|
|
infraPictureInfo.setFirstY(y1); |
|
|
|
infraPictureInfo.setSecondX(x2); |
|
|
|
infraPictureInfo.setSecondY(y2); |
|
|
|
|
|
|
|
InfraredInfo drawStringMatrix = matrixTemperatureShow(c, infraredInfo.getMatrixWidth(), infraredInfo.getMatrixHeight(), infraredInfo.getTemperatureMatrix()); |
|
|
|
infraredInfo.setFrameMax(Math.round(drawStringMatrix.getFrameMax() * 100) / 100f); |
|
|
|
// 添加矩形标签 |
|
|
|
String line1 = "平均温度:" + String.format("%.2f", drawStringMatrix.getFrameAverage()); |
|
|
|
String line2 = "最高温度:" + String.format("%.2f", drawStringMatrix.getFrameMax()); |
|
|
|
String line3 = "最低温度:" + String.format("%.2f", drawStringMatrix.getFrameMin()); |
|
|
|
g2d.drawString(line1, rectX + 5, rectY + 15); |
|
|
|
g2d.drawString(line2, rectX + 5, rectY + 30); |
|
|
|
g2d.drawString(line3, rectX + 5, rectY + 45); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
g2d.dispose(); |
|
|
|
ByteArrayOutputStream os = new ByteArrayOutputStream(); |
|
|
|
ImageIO.write(annotatedImage, "jpg", os); |
|
|
|
InputStream inputStream = new ByteArrayInputStream(os.toByteArray()); |
|
|
|
|
|
|
|
picFtp(outputPath, inputStream, ftpUrlAddress, ftpUrlPort, ftpUrlAccount, ftpUrlPwd); |
|
|
|
|
|
|
|
} catch (IOException e) { |
|
|
|
System.err.println("处理图片时出错: " + e.getMessage()); |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
return outputPath; |
|
|
|
} |
|
|
|
|
|
|
|
//调用华软接口获取csv文件 |
|
|
|
public float[][] UploadFtpImage(String url, String type, String image) { |
|
|
|
log.info("imageName" + image); |
|
|
|
@ -1321,75 +850,6 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//解析获取csv文件温度 |
|
|
|
private float[][] parseCsvFromFtp(String csvUrl) throws IOException { |
|
|
|
|
|
|
|
FTPClient ftp = new FTPClient(); |
|
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
|
|
|
|
|
|
|
String protocol = hrFtpUrl.substring(0, 6); // "ftp://" |
|
|
|
String withoutProtocol = hrFtpUrl.substring(6); // "zthr02:zthr02@123.184.14.138:50021/" |
|
|
|
String[] userAndHost = withoutProtocol.split("@"); |
|
|
|
if (userAndHost.length != 2) { |
|
|
|
throw new IllegalArgumentException("URL 格式错误,缺少 @ 分隔符"); |
|
|
|
} |
|
|
|
String[] userPass = userAndHost[0].split(":"); |
|
|
|
String username = userPass[0]; |
|
|
|
String password = userPass[1]; |
|
|
|
String hostPort = userAndHost[1].replace("/", ""); // 移除末尾的 "/" |
|
|
|
String[] hostAndPort = hostPort.split(":"); |
|
|
|
String host = hostAndPort[0]; |
|
|
|
int port = Integer.parseInt(hostAndPort[1]); |
|
|
|
try { |
|
|
|
|
|
|
|
ftp.connect(host, port); |
|
|
|
ftp.login(username, password); |
|
|
|
ftp.enterLocalPassiveMode(); |
|
|
|
ftp.setFileType(FTP.BINARY_FILE_TYPE); |
|
|
|
|
|
|
|
|
|
|
|
String remotePath = csvUrl.replace(protocol + host + ":" + port, ""); |
|
|
|
|
|
|
|
|
|
|
|
if (!ftp.retrieveFile(remotePath, outputStream)) { |
|
|
|
throw new IOException("文件下载失败: " + remotePath); |
|
|
|
} |
|
|
|
|
|
|
|
byte[] csvData = outputStream.toByteArray(); |
|
|
|
try (InputStream inputStream = new ByteArrayInputStream(csvData); |
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { |
|
|
|
|
|
|
|
List<float[]> rows = new ArrayList<>(); |
|
|
|
String line; |
|
|
|
while ((line = reader.readLine()) != null) { |
|
|
|
if (line.trim().isEmpty()) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
String[] stringValues = line.split(","); |
|
|
|
float[] floatValues = new float[stringValues.length]; |
|
|
|
for (int i = 0; i < stringValues.length; i++) { |
|
|
|
try { |
|
|
|
floatValues[i] = Float.parseFloat(stringValues[i].trim()); |
|
|
|
} catch (NumberFormatException e) { |
|
|
|
throw new IOException("Invalid number format in CSV at value: " + stringValues[i], e); |
|
|
|
} |
|
|
|
} |
|
|
|
rows.add(floatValues); |
|
|
|
} |
|
|
|
float[][] result = new float[rows.size()][]; |
|
|
|
for (int i = 0; i < rows.size(); i++) { |
|
|
|
result[i] = rows.get(i); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
} finally { |
|
|
|
if (ftp.isConnected()) { |
|
|
|
ftp.disconnect(); |
|
|
|
} |
|
|
|
outputStream.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//从ftp获取csv流转换成二维数组 |
|
|
|
|
|
|
|
private float[][] parseCsvFromFtp2(String csvUrl) throws IOException, URISyntaxException { |
|
|
|
@ -1448,8 +908,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
} |
|
|
|
|
|
|
|
//上传图片到ftp |
|
|
|
public void picFtp(String newPath, InputStream originalPath, String ftpUrlAddress, Integer ftpUrlPort, String |
|
|
|
ftpUrlAccount, String ftpUrlPwd) { |
|
|
|
public void picFtp(String newPath, InputStream originalPath, String ftpUrlAddress, Integer ftpUrlPort, String ftpUrlAccount, String ftpUrlPwd) { |
|
|
|
FTPSClient ftps = null; |
|
|
|
try { |
|
|
|
ftps = new FTPSClient(true); |
|
|
|
@ -1481,52 +940,6 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//华软上传图片到ftp |
|
|
|
public boolean pic2Ftp(String newPath, InputStream originalPath, String ftpUrlAddress, Integer |
|
|
|
ftpUrlPort, String ftpUrlAccount, String ftpUrlPwd) { |
|
|
|
FTPClient ftps = new FTPClient(); |
|
|
|
ftps.setConnectTimeout(2000); // 连接超时3秒 |
|
|
|
ftps.setDataTimeout(2000); // 数据传输超时3秒 |
|
|
|
ftps.setDefaultTimeout(2000); // 控制通道超时3秒 |
|
|
|
try { |
|
|
|
// 尝试连接(仅一次) |
|
|
|
ftps.connect(ftpUrlAddress, ftpUrlPort); |
|
|
|
boolean loginRes = ftps.login(ftpUrlAccount, ftpUrlPwd); |
|
|
|
System.out.println(loginRes); |
|
|
|
// 登录(同样受3秒超时限制) |
|
|
|
if (!loginRes) { |
|
|
|
throw new IOException("登录失败: " + ftps.getReplyString()); |
|
|
|
} |
|
|
|
|
|
|
|
ftps.setFileType(2); |
|
|
|
ftps.enterLocalPassiveMode(); |
|
|
|
ftps.setControlEncoding("UTF-8"); |
|
|
|
// ftps.setFileTransferMode(10); |
|
|
|
boolean success = ftps.storeFile(newPath, originalPath); |
|
|
|
if (!success) { |
|
|
|
System.err.println("上传失败!FTP 返回: " + ftps.getReplyString()); |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
return false; |
|
|
|
} finally { |
|
|
|
// 5. 关闭资源 |
|
|
|
try { |
|
|
|
if (ftps.isConnected()) { |
|
|
|
ftps.disconnect(); // 直接断开,不执行logout(节省时间) |
|
|
|
} |
|
|
|
// if (originalPath != null) originalPath.close(); |
|
|
|
// if (ftps != null && ftps.isConnected()) { |
|
|
|
// ftps.logout(); |
|
|
|
// ftps.disconnect(); |
|
|
|
// } |
|
|
|
} catch (IOException e) { |
|
|
|
log.error("error" + e); |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
//ftp图片获取 |
|
|
|
public InputStream downloadFtp(String downloadPath) { |
|
|
|
InputStream inputStream = null; |
|
|
|
@ -1553,42 +966,6 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//异常处理返回本地csv |
|
|
|
private float[][] exceptionHandling() throws IOException { |
|
|
|
//i.csv文件存放到resources下 |
|
|
|
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("1.csv"); |
|
|
|
|
|
|
|
// String localPath = "/1.csv"; |
|
|
|
// InputStream inputStream = downloadFtp(localPath); |
|
|
|
if (inputStream == null) { |
|
|
|
log.error(Color.RED + "项目无法加载1.csv文件!"); |
|
|
|
return null; |
|
|
|
} |
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); |
|
|
|
List<float[]> rows = new ArrayList<>(); |
|
|
|
String line; |
|
|
|
while ((line = reader.readLine()) != null) { |
|
|
|
if (line.trim().isEmpty()) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
String[] stringValues = line.split(","); |
|
|
|
float[] floatValues = new float[stringValues.length]; |
|
|
|
for (int i = 0; i < stringValues.length; i++) { |
|
|
|
try { |
|
|
|
floatValues[i] = Float.parseFloat(stringValues[i].trim()); |
|
|
|
} catch (NumberFormatException e) { |
|
|
|
throw new IOException("Invalid number format in CSV at value: " + stringValues[i], e); |
|
|
|
} |
|
|
|
} |
|
|
|
rows.add(floatValues); |
|
|
|
} |
|
|
|
float[][] result = new float[rows.size()][]; |
|
|
|
for (int i = 0; i < rows.size(); i++) { |
|
|
|
result[i] = rows.get(i); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public ResponseEntity<String> irPicAnalyse(final String analyseRequestJson) { |
|
|
|
log.info("[INFRARED] irPicAnalyse: analyseRequestJson={}", analyseRequestJson); |
|
|
|
@ -1668,167 +1045,7 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
} |
|
|
|
|
|
|
|
public InfraredInfo calculatePicture(InfraPictureInfo infraPictureInfo, String picData) { |
|
|
|
|
|
|
|
log.info("进入红外图片接口!"); |
|
|
|
|
|
|
|
InfraredInfo infraredInfo = new InfraredInfo(); |
|
|
|
String imagePath = infraPictureInfo.getFilePath(); |
|
|
|
log.info("图片路径:{}", imagePath); |
|
|
|
//输出路径 |
|
|
|
int lastSlashIndex = imagePath.lastIndexOf('/'); |
|
|
|
picPath = (lastSlashIndex >= 0) ? imagePath.substring(0, lastSlashIndex + 1) : "/"; |
|
|
|
log.info("输出图片路径:{}", picPath); |
|
|
|
|
|
|
|
InputStream inputStream = downloadFtp(imagePath); |
|
|
|
int firstX = 1; |
|
|
|
int firstY = 1; |
|
|
|
int secondX = 639; |
|
|
|
int secondY = 511; |
|
|
|
int imgWidth = 640; |
|
|
|
int imgHeight = 512; |
|
|
|
if (picData != null) { |
|
|
|
String[] parts = picData.split(","); |
|
|
|
// 解析坐标 |
|
|
|
firstX = Integer.parseInt(parts[0]); |
|
|
|
firstY = Integer.parseInt(parts[1]); |
|
|
|
secondX = Integer.parseInt(parts[2]); |
|
|
|
secondY = Integer.parseInt(parts[3]); |
|
|
|
imgHeight = Integer.parseInt(parts[4]); |
|
|
|
imgWidth = Integer.parseInt(parts[5]); |
|
|
|
} else { |
|
|
|
log.error("无点位信息!"); |
|
|
|
} |
|
|
|
List<Coordinate> coordinates = new ArrayList<>(); |
|
|
|
coordinates.add(new Coordinate(firstX, firstY, secondX, secondY)); |
|
|
|
infraPictureInfo.setImgWidth(imgWidth); |
|
|
|
infraPictureInfo.setImgHeight(imgHeight); |
|
|
|
infraPictureInfo.setCoordinates(coordinates); |
|
|
|
|
|
|
|
final String imageType = infraPictureInfo.getImgType(); |
|
|
|
if (AlgConstants.INFRA_CAMERA.equals(imageType)) { |
|
|
|
//相机红外 |
|
|
|
byte[] imageBytes = new byte[0]; |
|
|
|
try { |
|
|
|
//ftp下载图片流转byte[] |
|
|
|
InputStream imgInputStream = downloadFtp(imagePath); |
|
|
|
imageBytes = IOUtils.toByteArray(imgInputStream); |
|
|
|
// imageBytes = Files.readAllBytes(Paths.get(imagePath)); |
|
|
|
//读取红外信息 |
|
|
|
infraredInfo = readDataHw(imageBytes, infraPictureInfo.getCoordinates().get(0)); |
|
|
|
//绘制框选标识 |
|
|
|
String s = ImageOverlays(infraPictureInfo, infraredInfo); |
|
|
|
infraredInfo.setOutPath(s); |
|
|
|
|
|
|
|
} catch (IOException e) { |
|
|
|
log.error("error" + e); |
|
|
|
} |
|
|
|
|
|
|
|
} else if (AlgConstants.INFRA_CAMERA_REVERSE.equals(imageType)) { |
|
|
|
//相机反算红外 |
|
|
|
InputStream inputStreamPath = downloadFtp(imagePath); |
|
|
|
|
|
|
|
float[][] matrix = tempCount.countTemp(inputStreamPath, 61.20, 7.10);//图,最高值,最低值 |
|
|
|
infraredInfo.setTemperatureMatrix(matrix); |
|
|
|
//画框标注 |
|
|
|
String s = ImageOverlays(infraPictureInfo, infraredInfo); |
|
|
|
infraredInfo.setOutPath(s); |
|
|
|
|
|
|
|
} else if (AlgConstants.INFRA_1800.equals(imageType)) { |
|
|
|
//ivs1800红外图 |
|
|
|
String s = ImageOverlays(infraPictureInfo, infraredInfo); |
|
|
|
infraredInfo.setOutPath(s); |
|
|
|
} else if (AlgConstants.INFRA_YU3.equals(imageType)) { |
|
|
|
//无人机红外图 |
|
|
|
if (!produceEnvironment) { |
|
|
|
//调用华软接口 |
|
|
|
String protocol = hrFtpUrl.substring(0, 6); // "ftp://" |
|
|
|
String withoutProtocol = hrFtpUrl.substring(6); // "zthr02:zthr02@123.184.14.138:50021/" |
|
|
|
String[] userAndHost = withoutProtocol.split("@"); |
|
|
|
if (userAndHost.length != 2) { |
|
|
|
throw new IllegalArgumentException("URL 格式错误,缺少 @ 分隔符"); |
|
|
|
} |
|
|
|
String[] userPass = userAndHost[0].split(":"); |
|
|
|
String username = userPass[0]; |
|
|
|
String password = userPass[1]; |
|
|
|
String hostPort = userAndHost[1].replace("/", ""); // 移除末尾的 "/" |
|
|
|
String[] hostAndPort = hostPort.split(":"); |
|
|
|
String host = hostAndPort[0]; |
|
|
|
int port = Integer.parseInt(hostAndPort[1]); |
|
|
|
String imageName = Paths.get(imagePath).getFileName().toString(); |
|
|
|
boolean isLoginHr = pic2Ftp(imageName, inputStream, host, port, username, password); |
|
|
|
String ftpUrlName = "[\"" + hrFtpUrl + imageName + "\"]"; |
|
|
|
|
|
|
|
|
|
|
|
float[][] imageTem = new float[0][]; |
|
|
|
if (isLoginHr) { |
|
|
|
//可以登陆华软ftp |
|
|
|
imageTem = UploadFtpImage(hrUavUrl, null, ftpUrlName); |
|
|
|
if (imageTem != null && imageTem.length > 0 && imageTem[0].length > 0) { |
|
|
|
infraredInfo.setTemperatureMatrix(imageTem); |
|
|
|
} else { |
|
|
|
//不能调用华软接口,使用本地csv |
|
|
|
try { |
|
|
|
imageTem = exceptionHandling(); |
|
|
|
infraredInfo.setTemperatureMatrix(imageTem); |
|
|
|
} catch (IOException e) { |
|
|
|
log.error("error" + e); |
|
|
|
log.error("温度解析错误,接口无法调用!"); |
|
|
|
} |
|
|
|
} |
|
|
|
String s = ImageOverlays(infraPictureInfo, infraredInfo); |
|
|
|
infraredInfo.setOutPath(s); |
|
|
|
} else { |
|
|
|
//华软ftp不能登录,使用本地csv |
|
|
|
try { |
|
|
|
imageTem = exceptionHandling(); |
|
|
|
infraredInfo.setTemperatureMatrix(imageTem); |
|
|
|
} catch (IOException e) { |
|
|
|
log.error("error" + e); |
|
|
|
log.error("温度解析错误,ftp无法登陆!" + e); |
|
|
|
} |
|
|
|
String s = ImageOverlays(infraPictureInfo, infraredInfo); |
|
|
|
infraredInfo.setOutPath(s); |
|
|
|
} |
|
|
|
} else { |
|
|
|
String imageName = Paths.get(imagePath).getFileName().toString(); |
|
|
|
String ftpUrlName = "[\"ftp://" + ftpUrlAccount + ":" + ftpUrlPwd + "@" + ftpUrlAddress + ":" + ftpUrlPort + imagePath + "\"]"; |
|
|
|
float[][] floats = new float[0][]; |
|
|
|
floats = UploadFtpImage(hrUavUrl, null, ftpUrlName); |
|
|
|
if (floats != null && floats.length > 0 && floats[0].length > 0) { |
|
|
|
infraredInfo.setTemperatureMatrix(floats); |
|
|
|
log.info("配置的点位" + infraPictureInfo.getFirstX(), infraPictureInfo.getFirstY()); |
|
|
|
String s = ImageOverlays(infraPictureInfo, infraredInfo); |
|
|
|
infraredInfo.setOutPath(s); |
|
|
|
} else { |
|
|
|
//不能调用华软接口,使用本地csv |
|
|
|
try { |
|
|
|
floats = exceptionHandling(); |
|
|
|
infraredInfo.setTemperatureMatrix(floats); |
|
|
|
} catch (IOException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
log.error("温度解析错误,接口无法调用!"); |
|
|
|
} |
|
|
|
String s = ImageOverlays(infraPictureInfo, infraredInfo); |
|
|
|
infraredInfo.setOutPath(s); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else if (infraPictureInfo.getImgType().equals("infra_yu3_sdk")) { |
|
|
|
|
|
|
|
//无人机红外图 sdk版本调用x64 |
|
|
|
// try { |
|
|
|
// float[][] imageTem = djService.getImageTem("D:/projects/pic/hw/1.JPG"); |
|
|
|
// for (int i = 0; i < imageTem.length; i++) { |
|
|
|
// for (int j = 0; j < imageTem[i].length; j++) { |
|
|
|
// System.out.printf("%6.2f ", imageTem[i][j]); // 保留2位小数,固定宽度 |
|
|
|
// } |
|
|
|
// System.out.println(); // 换行 |
|
|
|
// } |
|
|
|
// |
|
|
|
// } catch (IOException e) { |
|
|
|
// e.printStackTrace(); |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
return infraredInfo; |
|
|
|
} |
|
|
|
@ -1923,96 +1140,6 @@ public class HikVisionServiceImpl implements HikVisionService { |
|
|
|
return fileName + ".csv"; |
|
|
|
} |
|
|
|
|
|
|
|
//解析获取csv文件温度--返回流文件 |
|
|
|
private InputStream getFtpFileAsStream(String csvUrl) throws IOException { |
|
|
|
|
|
|
|
FTPClient ftp = new FTPClient(); |
|
|
|
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
|
|
|
|
|
|
|
|
|
|
|
String protocol = hrFtpUrl.substring(0, 6); // "ftp://" |
|
|
|
String withoutProtocol = hrFtpUrl.substring(6); // "zthr02:zthr02@123.184.14.138:50021/" |
|
|
|
String[] userAndHost = withoutProtocol.split("@"); |
|
|
|
if (userAndHost.length != 2) { |
|
|
|
throw new IllegalArgumentException("URL 格式错误,缺少 @ 分隔符"); |
|
|
|
} |
|
|
|
String[] userPass = userAndHost[0].split(":"); |
|
|
|
String username = userPass[0]; |
|
|
|
String password = userPass[1]; |
|
|
|
String hostPort = userAndHost[1].replace("/", ""); // 移除末尾的 "/" |
|
|
|
String[] hostAndPort = hostPort.split(":"); |
|
|
|
String host = hostAndPort[0]; |
|
|
|
int port = Integer.parseInt(hostAndPort[1]); |
|
|
|
|
|
|
|
ftp.connect(host, port); |
|
|
|
ftp.login(username, password); |
|
|
|
ftp.enterLocalPassiveMode(); |
|
|
|
ftp.setFileType(FTP.BINARY_FILE_TYPE); |
|
|
|
|
|
|
|
String remotePath = csvUrl.replace(protocol + host + ":" + port, ""); |
|
|
|
|
|
|
|
InputStream inputStream = ftp.retrieveFileStream(remotePath); |
|
|
|
return inputStream; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//调用华软接口获取csv文件,转成流文件 |
|
|
|
public InputStream UploadFtpImageStream(String url, String image) { |
|
|
|
InputStream inputStream = null; |
|
|
|
OkHttpClient client = new OkHttpClient.Builder() |
|
|
|
.connectTimeout(5, TimeUnit.SECONDS) // 连接超时5秒 |
|
|
|
.readTimeout(10, TimeUnit.SECONDS) // 读取超时10秒 |
|
|
|
.writeTimeout(5, TimeUnit.SECONDS) // 写入超时5秒 |
|
|
|
.retryOnConnectionFailure(false) // 禁用自动重试 |
|
|
|
.build(); |
|
|
|
try { |
|
|
|
// 构建 multipart 请求体 |
|
|
|
RequestBody requestBody = new MultipartBody.Builder() |
|
|
|
.setType(MultipartBody.FORM) |
|
|
|
.addFormDataPart("type", "ftp") |
|
|
|
.addFormDataPart("image", image) |
|
|
|
.build(); |
|
|
|
|
|
|
|
// 构建请求 |
|
|
|
Request request = new Request.Builder() |
|
|
|
.url(url) |
|
|
|
.post(requestBody) |
|
|
|
.addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)") |
|
|
|
.addHeader("Accept", "*/*") |
|
|
|
.addHeader("Connection", "keep-alive") |
|
|
|
.build(); |
|
|
|
|
|
|
|
// 执行请求并处理响应 |
|
|
|
try (Response response = client.newCall(request).execute()) { |
|
|
|
if (!response.isSuccessful()) { |
|
|
|
throw new IOException("请求失败,HTTP状态码: " + response.code()); |
|
|
|
} |
|
|
|
|
|
|
|
String responseBody = response.body() != null ? response.body().string() : null; |
|
|
|
if (responseBody == null) { |
|
|
|
throw new IOException("响应体为空"); |
|
|
|
} |
|
|
|
// 解析 JSON 并提取 image_raw_flow |
|
|
|
ObjectMapper mapper = new ObjectMapper(); |
|
|
|
JsonNode jsonArray = mapper.readTree(responseBody); |
|
|
|
if (jsonArray.isEmpty()) { |
|
|
|
throw new RuntimeException("JSON数组为空"); |
|
|
|
} |
|
|
|
JsonNode firstItem = jsonArray.get(0); |
|
|
|
String imageRawFlow = firstItem.get("image_raw_flow").asText(); |
|
|
|
InputStream ftpFileAsStream = getFtpFileAsStream(imageRawFlow); |
|
|
|
// byte[] ftpFileAsStream = getFtpFileAsStream("ftp://123.184.14.138:50021/1.csv"); |
|
|
|
|
|
|
|
if (ftpFileAsStream != null) { |
|
|
|
inputStream = ftpFileAsStream; |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
System.err.println("FTP请求处理失败"); |
|
|
|
} |
|
|
|
return inputStream; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public int insertInfraredBoxList(InfraPictureInfo infraPictureInfo) { |
|
|
|
|