SignageFileUtil.java 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package com.yeechart.dotMatrix.signage;
  2. import com.yeechart.dotMatrix.canvas.DotMatrixConversionUtil;
  3. import com.yeechart.dotMatrix.crc.CustomCRC32Util;
  4. import com.yeechart.dotMatrix.minilzo.MiniLZO;
  5. import com.yeechart.dotMatrix.minilzo.MiniLZOUtil;
  6. import com.yeechart.dotMatrix.minilzo.bean.MInt;
  7. import com.yeechart.dotMatrix.oss.LatticeOSSUpload;
  8. import com.yeechart.dotMatrix.oss.OSSUpload;
  9. import com.yeechart.dotMatrix.signage.bean.mizilzo.BitmapDataVo;
  10. import com.yeechart.dotMatrix.signage.bean.mizilzo.MiniLZOVo;
  11. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  12. import com.yeechart.dotMatrix.util.OtherUtil;
  13. import org.slf4j.Logger;
  14. import org.slf4j.LoggerFactory;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.stereotype.Component;
  17. import java.util.*;
  18. import java.util.concurrent.CompletableFuture;
  19. import java.util.concurrent.ThreadPoolExecutor;
  20. import java.util.stream.Collectors;
  21. /**
  22. * 对 点阵图 文件操作
  23. */
  24. @Component
  25. public class SignageFileUtil {
  26. /**
  27. * 终端类总路径名称
  28. */
  29. public static final String ROOT_FILE_NAME = "Device/";
  30. /**
  31. * 默认的文件名称
  32. */
  33. public static final String ROOT_FILE_TYPE_NAME = ".txt";
  34. public static String fileName = "device/020201/lattice/";//路径;
  35. protected static Logger logger = LoggerFactory.getLogger(SignageFileUtil.class);
  36. //private ThreadPoolExecutor threadPoolTaskExecutor = ThreadPoolTaskExecutor.getInstance().getThreadPoolExecutor();
  37. @javax.annotation.Resource
  38. private ThreadPoolTaskExecutor threadPoolTaskExecutor;
  39. @Autowired
  40. private LatticeOSSUpload latticeOSSUpload;
  41. @Autowired
  42. private OSSUpload ossUpload;
  43. /**
  44. * 获取最新的点阵图文件对象
  45. *
  46. * @param dId 设备ID
  47. * @param typeCode 功能code
  48. * @param isDefault 是否是默认图
  49. * @return
  50. */
  51. public BitmapDataVo getLastBitmapDataVo(String dId, String typeCode, boolean isDefault) {
  52. if (isDefault) {
  53. typeCode = "D" + typeCode;
  54. }
  55. String url = "http://" + ossUpload.getEndpoint() + "/" + fileName + dId + "/" + typeCode;
  56. BitmapDataVo bitmapDataVo = new BitmapDataVo();
  57. bitmapDataVo.setTypeCode(typeCode);
  58. bitmapDataVo.setPath(url);
  59. return getFileBitmapArrays(bitmapDataVo);
  60. }
  61. /**
  62. * 删除点阵图
  63. * @param dId 设备ID
  64. */
  65. public void deleteSignageDotMatrix(String dId){
  66. String url = "http://" + ossUpload.getEndpoint() + "/" + fileName + dId ;
  67. latticeOSSUpload.deleteFolderAndSubFolders(url);
  68. }
  69. /**
  70. * 从 指定路径中,获取对应的文件夹数据,并解压数据合并为原始数据
  71. *
  72. * @return
  73. */
  74. public BitmapDataVo getFileBitmapArrays(BitmapDataVo bitmapDataVo) {
  75. try {
  76. Map<String, byte[]> fileMap = new HashMap<>();
  77. CompletableFuture<Map<String, byte[]>> completableFuture = latticeOSSUpload.listFilesByPath(bitmapDataVo.getPath());
  78. fileMap = completableFuture.get();
  79. if (fileMap.isEmpty()) {
  80. return null;
  81. }
  82. //排序
  83. List<Map.Entry<String, byte[]>> entries = new ArrayList<>(fileMap.entrySet());
  84. Map<String, Integer> sizeMap = new HashMap<>();
  85. // 定义比较器,根据文件名最后两位数字进行排序
  86. entries.sort((entry1, entry2) -> {
  87. String name1 = entry1.getKey();
  88. String name2 = entry2.getKey();
  89. int lastDotIndex = name1.lastIndexOf('.');
  90. name1 = name1.substring(0, lastDotIndex);
  91. lastDotIndex = name2.lastIndexOf('.');
  92. name2 = name2.substring(0, lastDotIndex);
  93. int a1 = Integer.parseInt(name1.substring(name1.length() - 2));
  94. int a2 = Integer.parseInt(name2.substring(name2.length() - 2));
  95. return Integer.compare(a1, a2);
  96. });
  97. // 根据排序后的列表构造一个新的LinkedHashMap,以保持排序顺序
  98. Map<String, byte[]> sortedMap = new LinkedHashMap<>();
  99. for (Map.Entry<String, byte[]> entry : entries) {
  100. String name = entry.getKey();
  101. sortedMap.put(name, entry.getValue());
  102. //获取文件路径中的图的原始数据大小
  103. if (!sizeMap.containsKey(name)) {
  104. String sum = name.substring(0, name.lastIndexOf('/'));
  105. sizeMap.put(name, Integer.parseInt(sum));
  106. }
  107. }
  108. //整图的原始数据的大小 sizeMap 的value 总和
  109. String fileName = null;
  110. Integer ogSize = null;
  111. byte[] data = new byte[sizeMap.values().stream().mapToInt(Integer::intValue).sum()];
  112. int length = 0;
  113. Map<String, MiniLZOVo> miniLZOVoList = new HashMap<>();
  114. for (Map.Entry<String, byte[]> entry : sortedMap.entrySet()) {
  115. fileName = entry.getKey();
  116. ogSize = Integer.parseInt(fileName.substring(0, fileName.lastIndexOf('/')));
  117. byte[] dataBytes = entry.getValue();
  118. //解压缩
  119. byte[] dataBytes2 = new byte[ogSize];
  120. MInt outL2 = new MInt();
  121. MiniLZO.lzo1x_decompress(dataBytes, ogSize, dataBytes2, outL2);
  122. // logger.info("解压缩后的长度 outLen len:" +outL2.v);
  123. System.arraycopy(dataBytes2, 0, data, length, outL2.v);
  124. MiniLZOVo miniLZOVo = new MiniLZOVo();
  125. miniLZOVo.setOgSize(ogSize);
  126. miniLZOVo.setData(dataBytes);
  127. miniLZOVo.setCrc32(CustomCRC32Util.calculateCRC32(dataBytes2));
  128. miniLZOVoList.put(fileName, miniLZOVo);
  129. length = length + ogSize;
  130. }
  131. // byte[] dataBytes33 = new byte[4];
  132. // System.arraycopy(data,data.length-4,dataBytes33,0,4);
  133. byte[] dataBytes3 = new byte[data.length - 4];
  134. System.arraycopy(data, 0, dataBytes3, 0, data.length - 4);
  135. //将 16点阵数据 转换为 二进制点阵数据
  136. byte[] twoBytes = DotMatrixConversionUtil.sixteenTo2Lattice(data);
  137. bitmapDataVo.setMiniLZOVoList(miniLZOVoList);
  138. bitmapDataVo.setTwoData(twoBytes);
  139. return bitmapDataVo;
  140. } catch (Exception e) {
  141. e.printStackTrace();
  142. logger.error("获取 点阵图文件 :" + e + " 路径为 " + bitmapDataVo.getPath());
  143. }
  144. return null;
  145. }
  146. /************************************** 处理的点阵数据对象 **************************************/
  147. /**
  148. * 将完整的点阵图数据 转换为 点整图对象
  149. *
  150. * @param twoBytes
  151. * @param deId
  152. * @param path
  153. * @param typeCode
  154. * @param isDefault
  155. * @return
  156. */
  157. public BitmapDataVo dealWithBitmapDataVo(byte[] twoBytes, String deId, String path, String typeCode, boolean isDefault) {
  158. BitmapDataVo bitmapDataVo = new BitmapDataVo();
  159. bitmapDataVo.setTwoData(twoBytes);
  160. bitmapDataVo.setTime(System.currentTimeMillis());
  161. //区分默认点阵图
  162. if (isDefault) {
  163. typeCode = "D" + typeCode;
  164. }
  165. bitmapDataVo.setTypeCode(typeCode);
  166. bitmapDataVo.setPath(path + typeCode);
  167. //保存文件
  168. Map<String, MiniLZOVo> sizeMap = dealWithMiniLZOVo(typeCode, twoBytes);
  169. bitmapDataVo.setMiniLZOVoList(sizeMap);
  170. return bitmapDataVo;
  171. }
  172. /**
  173. * 将完整的点阵图数据 进行 分割并压缩
  174. *
  175. * @param typeCode
  176. * @param twoBytes
  177. * @return
  178. */
  179. public Map<String, MiniLZOVo> dealWithMiniLZOVo(String typeCode, byte[] twoBytes) {
  180. Map<String, MiniLZOVo> sizeMap = new HashMap<>();
  181. // 将二进制点阵图转换为16进制点阵图
  182. byte[] dataBytes2 = DotMatrixConversionUtil.twoTo16Lattice(twoBytes);
  183. //2024/04/09 新增 在整体点阵数据后面追加整体CRC32的值
  184. //进行CRC32算法
  185. long crc32 = CustomCRC32Util.calculateCRC32(dataBytes2);
  186. byte[] crc32Bytes = OtherUtil.longToByteArray(crc32, 4);//固定4位
  187. byte[] dataBytes = new byte[dataBytes2.length + crc32Bytes.length];
  188. System.arraycopy(dataBytes2, 0, dataBytes, 0, dataBytes2.length);
  189. System.arraycopy(crc32Bytes, 0, dataBytes, dataBytes2.length, crc32Bytes.length);
  190. //将16进制点阵图进行压缩
  191. List<MiniLZOVo> miniLZOVoList = MiniLZOUtil.getInstance().subMiniLZO(dataBytes);
  192. //生成对应的文件名称
  193. for (int i = 0; i < miniLZOVoList.size(); i++) {
  194. String fileName = typeCode +
  195. (i < 10 ? "0" + i : i) + ROOT_FILE_TYPE_NAME;
  196. MiniLZOVo miniLZOVo = miniLZOVoList.get(i);
  197. sizeMap.put(miniLZOVo.getOgSize() + "/" + fileName, miniLZOVo);
  198. }
  199. return sizeMap;
  200. }
  201. }