From 1474746864224f736e4203f5a359af14b619b9e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=9F=B3=E5=A4=B4=E4=BA=BA?= <3076767823@qq.com>
Date: Fri, 17 Jan 2025 15:15:23 +0800
Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=A2=9E=E5=8A=A0=E5=9B=BE?=
=?UTF-8?q?=E7=89=87=E6=89=93=E5=8D=B0=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 10 +++
.../autoReplyPrint/base/BaseImagePrint.java | 89 +++++++++++++++++++
.../controller/ImagePrintController.java | 78 ++++++++++++++++
.../service/ImagePrintService.java | 59 ++++++++++++
.../impl/USBImagePrintServiceImpl.java | 56 ++++++++++++
.../autoReplyPrint/utils/ImageUtils.java | 85 ++++++++++++++++++
6 files changed, 377 insertions(+)
create mode 100644 src/main/java/com/dpkj/modules/autoReplyPrint/base/BaseImagePrint.java
create mode 100644 src/main/java/com/dpkj/modules/autoReplyPrint/controller/ImagePrintController.java
create mode 100644 src/main/java/com/dpkj/modules/autoReplyPrint/service/ImagePrintService.java
create mode 100644 src/main/java/com/dpkj/modules/autoReplyPrint/service/impl/USBImagePrintServiceImpl.java
create mode 100644 src/main/java/com/dpkj/modules/autoReplyPrint/utils/ImageUtils.java
diff --git a/pom.xml b/pom.xml
index 66e8b55..3f0b1c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,6 +21,8 @@
5.8.25
5.14.0
3.0.2
+ 1.2.83
+
@@ -68,6 +70,14 @@
pdfbox
${pdfbox.version}
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
+
+
diff --git a/src/main/java/com/dpkj/modules/autoReplyPrint/base/BaseImagePrint.java b/src/main/java/com/dpkj/modules/autoReplyPrint/base/BaseImagePrint.java
new file mode 100644
index 0000000..b19cf0a
--- /dev/null
+++ b/src/main/java/com/dpkj/modules/autoReplyPrint/base/BaseImagePrint.java
@@ -0,0 +1,89 @@
+package com.dpkj.modules.autoReplyPrint.base;
+
+import com.dpkj.common.exception.RRException;
+import com.dpkj.modules.autoReplyPrint.utils.AutoReplyPrint;
+import com.dpkj.modules.autoReplyPrint.utils.ImageUtils;
+import com.sun.jna.Pointer;
+import org.springframework.web.multipart.MultipartFile;
+
+
+/**
+ * 图片打印基础实现
+ *
+ * @author 石头人
+ * @version 1.0
+ * @since 2025-01-17 14:37:23
+ */
+public abstract class BaseImagePrint {
+
+ /**
+ * 必须要实现这个,获取句柄
+ * @param devName 设备名称
+ * @return 窗口句柄
+ */
+ public abstract Pointer getHandle(String devName);
+
+
+ public void printFromPath(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method) {
+ Pointer handle = getHandle(devName);
+ try {
+ // 开始打印图片
+ boolean printTag = AutoReplyPrint.INSTANCE.CP_Pos_PrintRasterImageFromFile(handle, dstw, dsth, pszFile, binaryzation_method, compression_method);
+ if( !printTag ){
+ throw new RRException("打印图片失败");
+ }
+
+ // 切纸
+ AutoReplyPrint.INSTANCE.CP_BlackMark_SetBlackMarkPaperCutPosition(handle, 0);
+ boolean cutPaper = AutoReplyPrint.INSTANCE.CP_Pos_FeedAndHalfCutPaper(handle);
+ if ( !cutPaper){
+ throw new RRException("图片裁剪失败,请自行裁剪");
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ throw new RRException(e);
+ }finally {
+ if ( handle != null) AutoReplyPrint.INSTANCE.CP_Port_Close(handle);
+ }
+ }
+
+
+ public void printFromPathData(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method) {
+ // 获取图片
+ byte[] data = ImageUtils.imageToBytes(pszFile);
+ this.printFromData(devName, dstw, dsth, data, binaryzation_method, compression_method);
+ }
+
+
+ public void printFromData(String devName, int dstw, int dsth, byte[] data, int binaryzation_method, int compression_method) {
+ Pointer handle = getHandle(devName);
+ try {
+ // 开始打印图片
+ boolean printTag = AutoReplyPrint.INSTANCE.CP_Pos_PrintRasterImageFromData(handle, dstw, dsth, data, data.length, binaryzation_method, compression_method);
+ if( !printTag ){
+ throw new RRException("打印图片失败");
+ }
+
+ // 切纸
+ AutoReplyPrint.INSTANCE.CP_BlackMark_SetBlackMarkPaperCutPosition(handle, 0);
+ boolean cutPaper = AutoReplyPrint.INSTANCE.CP_Pos_FeedAndHalfCutPaper(handle);
+ if ( !cutPaper){
+ throw new RRException("图片裁剪失败,请自行裁剪");
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ throw new RRException(e);
+ }finally {
+ if ( handle != null) AutoReplyPrint.INSTANCE.CP_Port_Close(handle);
+ }
+ }
+
+
+ public void printFromMultipartFile(String devName, int dstw, int dsth, MultipartFile file, int binaryzation_method, int compression_method){
+ byte[] data = ImageUtils.getByteToMultipartFile(file);
+ this.printFromData(devName, dstw, dsth, data, binaryzation_method, compression_method);
+ }
+
+
+}
+
diff --git a/src/main/java/com/dpkj/modules/autoReplyPrint/controller/ImagePrintController.java b/src/main/java/com/dpkj/modules/autoReplyPrint/controller/ImagePrintController.java
new file mode 100644
index 0000000..9c97d2e
--- /dev/null
+++ b/src/main/java/com/dpkj/modules/autoReplyPrint/controller/ImagePrintController.java
@@ -0,0 +1,78 @@
+package com.dpkj.modules.autoReplyPrint.controller;
+
+import com.dpkj.common.vo.Result;
+import com.dpkj.modules.autoReplyPrint.service.ImagePrintService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+
+/**
+ * 图片打印控制层
+ *
+ * @author 石头人
+ * @version 1.0
+ * @since 2025-01-17 13:57:11
+ */
+@RequestMapping("/autoReplyPrint")
+public class ImagePrintController {
+
+ @Resource(name = "USBImagePrint")
+ private ImagePrintService usbImagePrintService;
+
+ /**
+ * 图片打印,通过路径
+ */
+ @GetMapping("/usb/imagePrint/path")
+ Result usbImagePrintFromPath(@RequestParam(defaultValue = "VID:0x0FE6,PID:0x811E") String usbName,
+ @RequestParam(defaultValue = "500") Integer width,
+ @RequestParam(defaultValue = "500") Integer height,
+ @RequestParam String path, Integer binaryMethod, Integer compressionMethod){
+ this.usbImagePrintService.imagePrintFromPath(usbName, width, height, path, binaryMethod, compressionMethod);
+ return Result.ok("图片打印成功");
+ }
+
+
+ /**
+ * 图片打印,通过byte[]
+ */
+ @GetMapping("/usb/imagePrint/pathData")
+ Result usbImagePrintFromData(@RequestParam(defaultValue = "VID:0x0FE6,PID:0x811E") String usbName,
+ @RequestParam(defaultValue = "500") Integer width,
+ @RequestParam(defaultValue = "500") Integer height,
+ @RequestParam String path, Integer binaryMethod, Integer compressionMethod){
+ this.usbImagePrintService.imagePrintFromPathData(usbName, width, height, path, binaryMethod, compressionMethod);
+ return Result.ok("图片打印成功");
+ }
+
+
+ /**
+ * 图片打印,通过multipartFile文件
+ */
+ @GetMapping("/usb/imagePrint/multipartFile")
+ Result usbImagePrintFromData(@RequestParam(defaultValue = "VID:0x0FE6,PID:0x811E") String usbName,
+ @RequestParam(defaultValue = "500") Integer width,
+ @RequestParam(defaultValue = "500") Integer height,
+ @RequestParam MultipartFile file, Integer binaryMethod, Integer compressionMethod){
+ this.usbImagePrintService.imagePrintFromMultipartFile(usbName, width, height, file, binaryMethod, compressionMethod);
+ return Result.ok("图片打印成功");
+ }
+
+
+ /**
+ * 图片打印,通过byte[]
+ */
+ @GetMapping("/usb/imagePrint/data")
+ Result usbImagePrintFromData(@RequestParam(defaultValue = "VID:0x0FE6,PID:0x811E") String usbName,
+ @RequestParam(defaultValue = "500") Integer width,
+ @RequestParam(defaultValue = "500") Integer height,
+ @RequestParam byte[] data, Integer binaryMethod, Integer compressionMethod){
+ this.usbImagePrintService.imagePrintFromData(usbName, width, height, data, binaryMethod, compressionMethod);
+ return Result.ok("图片打印成功");
+ }
+
+
+}
+
diff --git a/src/main/java/com/dpkj/modules/autoReplyPrint/service/ImagePrintService.java b/src/main/java/com/dpkj/modules/autoReplyPrint/service/ImagePrintService.java
new file mode 100644
index 0000000..e823ceb
--- /dev/null
+++ b/src/main/java/com/dpkj/modules/autoReplyPrint/service/ImagePrintService.java
@@ -0,0 +1,59 @@
+package com.dpkj.modules.autoReplyPrint.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 图片打印服务接口
+ *
+ * @author 石头人
+ * @version 1.0
+ * @since 2025-01-17 11:38:36
+ */
+public interface ImagePrintService {
+
+ /**
+ * 图片打印
+ * @param devName 设备名称/usb/tcp/com
+ * @param dstw 要打印的宽度
+ * @param dsth 要打印的高度
+ * @param pszFile 图片的路径
+ * @param binaryzation_method 图片二值化算法。0 表示抖动算法,1 表示阀值算法,2 表示误差扩散法。具体效果请测试查看。
+ * @param compression_method 最终打印数据的压缩方式,各值定义如下:0 不压缩,1 一级压缩,2 二级压缩。
+ */
+ void imagePrintFromPath(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method);
+
+ /**
+ * 图片打印,内部直接读取转换为byte进行打印
+ * @param devName 设备名称/usb/tcp/com
+ * @param dstw 要打印的宽度
+ * @param dsth 要打印的高度
+ * @param pszFile 图片的路径
+ * @param binaryzation_method 图片二值化算法。0 表示抖动算法,1 表示阀值算法,2 表示误差扩散法。具体效果请测试查看。
+ * @param compression_method 最终打印数据的压缩方式,各值定义如下:0 不压缩,1 一级压缩,2 二级压缩。
+ */
+ void imagePrintFromPathData(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method);
+
+ /**
+ * 直接传输数据进行打印
+ * @param devName 设备名称/usb/tcp/com
+ * @param dstw 要打印的宽度
+ * @param dsth 要打印的高度
+ * @param data 图片数据
+ * @param binaryzation_method 图片二值化算法。0 表示抖动算法,1 表示阀值算法,2 表示误差扩散法。具体效果请测试查看。
+ * @param compression_method 最终打印数据的压缩方式,各值定义如下:0 不压缩,1 一级压缩,2 二级压缩。
+ */
+ void imagePrintFromData(String devName, int dstw, int dsth, byte[] data, int binaryzation_method, int compression_method);
+
+ /**
+ * 直接传的MultipartFile文件过来
+ * @param devName 设备名称/usb/tcp/com
+ * @param dstw 要打印的宽度
+ * @param dsth 要打印的高度
+ * @param file 图片数据
+ * @param binaryzation_method 图片二值化算法。0 表示抖动算法,1 表示阀值算法,2 表示误差扩散法。具体效果请测试查看。
+ * @param compression_method 最终打印数据的压缩方式,各值定义如下:0 不压缩,1 一级压缩,2 二级压缩。
+ */
+ void imagePrintFromMultipartFile(String devName, int dstw, int dsth, MultipartFile file, int binaryzation_method, int compression_method);
+
+
+}
diff --git a/src/main/java/com/dpkj/modules/autoReplyPrint/service/impl/USBImagePrintServiceImpl.java b/src/main/java/com/dpkj/modules/autoReplyPrint/service/impl/USBImagePrintServiceImpl.java
new file mode 100644
index 0000000..6c69750
--- /dev/null
+++ b/src/main/java/com/dpkj/modules/autoReplyPrint/service/impl/USBImagePrintServiceImpl.java
@@ -0,0 +1,56 @@
+package com.dpkj.modules.autoReplyPrint.service.impl;
+
+import com.dpkj.common.exception.RRException;
+import com.dpkj.modules.autoReplyPrint.base.BaseImagePrint;
+import com.dpkj.modules.autoReplyPrint.service.ImagePrintService;
+import com.dpkj.modules.autoReplyPrint.utils.AutoReplyPrint;
+import com.sun.jna.Pointer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+
+/**
+ * 图片打印服务
+ *
+ * @author 石头人
+ * @version 1.0
+ * @since 2025-01-17 11:38:36
+ */
+@Slf4j
+@Service("USBImagePrint")
+public class USBImagePrintServiceImpl extends BaseImagePrint implements ImagePrintService {
+
+ @Override
+ public Pointer getHandle(String devName) {
+ try {
+ return AutoReplyPrint.INSTANCE.CP_Port_OpenUsb(devName, 1);
+ }catch (Exception e){
+ e.printStackTrace();
+ throw new RRException("获取USB句柄失败");
+ }
+ }
+
+ @Override
+ public void imagePrintFromPath(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method) {
+ super.printFromPath(devName, dstw, dsth, pszFile, binaryzation_method, compression_method);
+ }
+
+ @Override
+ public void imagePrintFromPathData(String devName, int dstw, int dsth, String pszFile, int binaryzation_method, int compression_method) {
+ super.printFromPathData(devName, dstw, dsth, pszFile, binaryzation_method, compression_method);
+ }
+
+ @Override
+ public void imagePrintFromData(String devName, int dstw, int dsth, byte[] data, int binaryzation_method, int compression_method) {
+ super.printFromData(devName, dstw, dsth, data, binaryzation_method, compression_method);
+ }
+
+ @Override
+ public void imagePrintFromMultipartFile(String devName, int dstw, int dsth, MultipartFile file, int binaryzation_method, int compression_method) {
+ super.printFromMultipartFile(devName, dstw, dsth, file, binaryzation_method, compression_method);
+ }
+
+
+}
+
diff --git a/src/main/java/com/dpkj/modules/autoReplyPrint/utils/ImageUtils.java b/src/main/java/com/dpkj/modules/autoReplyPrint/utils/ImageUtils.java
new file mode 100644
index 0000000..f358ea2
--- /dev/null
+++ b/src/main/java/com/dpkj/modules/autoReplyPrint/utils/ImageUtils.java
@@ -0,0 +1,85 @@
+package com.dpkj.modules.autoReplyPrint.utils;
+
+import com.dpkj.common.exception.RRException;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 图片转换工具
+ *
+ * @author 石头人
+ * @version 1.0
+ * @since 2025-01-17 14:06:09
+ */
+public class ImageUtils {
+
+ /**
+ * 读取图片并转换为byte数组
+ * @param imagePath 图片路径
+ * @return byte数组
+ */
+ public static byte[] imageToBytes(String imagePath) {
+ try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(Paths.get(imagePath)));
+ ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+ while ((bytesRead = bis.read(buffer)) != -1) {
+ baos.write(buffer, 0, bytesRead);
+ }
+
+ return baos.toByteArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RRException("读取图片信息失败");
+ }
+ }
+
+
+ /**
+ * 获取文件byte[],通过 MultipartFile
+ * @param file 文件信息
+ * @return byte数组
+ */
+ public static byte[] getByteToMultipartFile(MultipartFile file){
+ // 验证文件是否为空
+ if (file.isEmpty()) {
+ throw new RRException("文件内容为空");
+ }
+
+ // 验证文件类型
+ String contentType = file.getContentType();
+ if (contentType == null || !contentType.startsWith("image/")) {
+ throw new RRException("只支持图片文件");
+ }
+
+ // 获取文件扩展名
+ String fileName = file.getOriginalFilename();
+ String fileExtension = fileName != null ?
+ fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase() : "";
+
+ // 验证扩展名
+ List allowedExtensions = Arrays.asList("jpg", "jpeg", "png", "gif");
+ if (!allowedExtensions.contains(fileExtension)) {
+ throw new RRException("不支持的文件格式");
+ }
+
+ try {
+ // 转换为字节数组
+ return file.getBytes();
+ }catch (Exception e){
+ e.printStackTrace();
+ throw new RRException("获取文件字节失败");
+ }
+ }
+
+
+
+}
+