commit f1dc9ca1f7a9e0acc91a9abc9dfb246e2e6bc00f Author: 刘福顺 Date: Mon May 13 14:41:54 2024 +0800 1. 首次提交 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f9976ab --- /dev/null +++ b/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + org.aohe + sane-service + 1.0-SNAPSHOT + + + 21 + 21 + UTF-8 + + + + + com.googlecode.jfreesane + jfreesane + 1.0 + + + ch.qos.logback + logback-classic + 1.4.14 + + + com.alibaba.fastjson2 + fastjson2 + 2.0.37 + + + cn.hutool + hutool-all + 5.8.25 + + + org.projectlombok + lombok + true + 1.18.30 + + + + + \ No newline at end of file diff --git a/src/main/java/org/aohe/Main.java b/src/main/java/org/aohe/Main.java new file mode 100644 index 0000000..06bf688 --- /dev/null +++ b/src/main/java/org/aohe/Main.java @@ -0,0 +1,7 @@ +package org.aohe; + +public class Main { + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} \ No newline at end of file diff --git a/src/main/java/org/aohe/core/package-info.java b/src/main/java/org/aohe/core/package-info.java new file mode 100644 index 0000000..2f2c548 --- /dev/null +++ b/src/main/java/org/aohe/core/package-info.java @@ -0,0 +1 @@ +package org.aohe.core; \ No newline at end of file diff --git a/src/main/java/org/aohe/core/result/R.java b/src/main/java/org/aohe/core/result/R.java new file mode 100644 index 0000000..02d3053 --- /dev/null +++ b/src/main/java/org/aohe/core/result/R.java @@ -0,0 +1,39 @@ +package org.aohe.core.result; +import cn.hutool.json.JSONUtil; +import lombok.Data; + +@Data +public class R { + + private String code; + + private String msg; + + private T data; + + private boolean success; + + public R(String code, String msg, T data, boolean success) { + this.code = code; + this.msg = msg; + this.data = data; + this.success = success; + } + + public static R ok(Object data) { + return new R<>("200", "ok", data, true); + } + + public static R ok() { + return new R<>("200", "ok", null, true); + } + + public static R fail(String msg) { + return new R<>("500", msg, null, false); + } + + public String toJsonStr() { + return JSONUtil.toJsonStr(this); + } +} + diff --git a/src/main/java/org/aohe/core/sane/SaneOperational.java b/src/main/java/org/aohe/core/sane/SaneOperational.java new file mode 100644 index 0000000..cd87c1f --- /dev/null +++ b/src/main/java/org/aohe/core/sane/SaneOperational.java @@ -0,0 +1,129 @@ +package org.aohe.core.sane; + +import au.com.southsky.jfreesane.SaneDevice; +import au.com.southsky.jfreesane.SaneException; +import cn.hutool.core.codec.Base64; +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.aohe.core.result.R; +import org.aohe.core.sane.utils.SaneSessionUtils; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +public class SaneOperational { + + public static String selectOperational(String path) { + + JSONObject json = JSONObject.parse(path); + + //操作符 + String function = json.getString("function"); + + //参数符 + JSONObject param = json.getJSONObject("params"); + + R r = R.ok(); + try { + if("001001".equals(function)){ + //获取扫描仪列表 + r = getDeviceList(); + } else if ("001002".equals(function)) { + //选择扫描仪 + r = setScanner(param.getString("scannerId")); + }else if ("001003".equals(function)){ + //获取扫描仪操作符列表 + // r = getDeviceOperations(); + }else if ("001004".equals(function)){ + //r = setDeviceOperations(); + }else if ("001007".equals(function)){ + //r = setDeviceOperations(param); + }else if ("001008".equals(function)){ + r = startScan(param); + }else if ("001012".equals(function)){ + //closeTwSource(); + }else if ("001013".equals(function)){ + //closeTwSource(); + }else if ("001015".equals(function)){ + //r = startScan(param.getString("scannerId"),true); + }else if ("001016".equals(function)){ + //r = startScan(param.getString("scannerId"),true); + } + }catch (Exception e){ + log.info("Error , ", e); + } + + + return r.toJsonStr(); + } + + /** + * 001001 获取扫描仪列表 + * @return 返回扫描仪列表 + */ + public static R getDeviceList(){ + try { + List saneDevices = SaneSessionUtils.getSaneDrivers(); + List names = saneDevices.stream().map(SaneDevice::getName).collect(Collectors.toList()); + return R.ok(names); + } catch (IOException | SaneException e) { + log.error("Not found scan list", e); + return R.fail("Not found scan list"); + } + } + + private static String saneDrivers = null; + + /** + * 001002 选择扫描仪 + * @param scannerId 扫描仪id + * @return 返回成功 + */ + public static R setScanner(String scannerId){ + try { + if(saneDrivers == null){ + saneDrivers = scannerId; + } + + SaneSessionUtils.setSaneDevice(scannerId); + return R.ok(); + } catch (SaneException | IOException e) { + throw new RuntimeException(e); + } + } + + /** + * 001007 设置扫描仪参数 + * @param params 扫描仪参数 + * @return 返回成功 + */ +// public static R setDeviceOperations(JSONObject params){ +// try { +// SaneSeesionUtils.setOption(params); +// } catch (TwainException e) { +// log.error("scan setting is not set", e); +// return R.fail("scan setting is not set, please select scan "); +// } +// return R.ok(); +// } + + public static R startScan(JSONObject params){ + try { + File files = SaneSessionUtils.getSaneFile(); + Map map = new HashMap<>(); + map.put(files.getName(),Base64.encode(files)); + List> list = new ArrayList<>(); + list.add(map); + + return R.ok(list); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/org/aohe/core/sane/utils/RemoteConfig.java b/src/main/java/org/aohe/core/sane/utils/RemoteConfig.java new file mode 100644 index 0000000..5cba167 --- /dev/null +++ b/src/main/java/org/aohe/core/sane/utils/RemoteConfig.java @@ -0,0 +1,27 @@ +package org.aohe.core.sane.utils; + +import cn.hutool.setting.Setting; +import lombok.Data; + + +@Data +public class RemoteConfig { + + private String ip = "127.0.0.1"; + + RemoteConfig() { + } + + RemoteConfig(String ip) { + this.ip = ip; + } + + public static RemoteConfig getInstance(){ + String ip = new Setting("config.setting").get("ip"); + if(ip != null){ + return new RemoteConfig(ip); + } + return new RemoteConfig(); + } + +} diff --git a/src/main/java/org/aohe/core/sane/utils/SaneSessionUtils.java b/src/main/java/org/aohe/core/sane/utils/SaneSessionUtils.java new file mode 100644 index 0000000..8eb0813 --- /dev/null +++ b/src/main/java/org/aohe/core/sane/utils/SaneSessionUtils.java @@ -0,0 +1,173 @@ +package org.aohe.core.sane.utils; + +import au.com.southsky.jfreesane.SaneDevice; +import au.com.southsky.jfreesane.SaneException; +import au.com.southsky.jfreesane.SaneSession; +import cn.hutool.core.io.FileUtil; +import com.alibaba.fastjson2.JSON; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.util.List; + +@Slf4j +public class SaneSessionUtils { + + private static final Object lock = new Object(); + + private static volatile SaneSession saneSession; + + private static volatile SaneDevice saneDevice; + + private static final RemoteConfig remoteConfig = RemoteConfig.getInstance(); + + /** + * 获取一个SaneSession实例,用于与SANE设备进行通信 + * @return SaneSession实例 + * @throws IOException 如果获取SaneSession实例时发生I/O错误 + */ + public static SaneSession getSaneSession() throws IOException { + log.info("saneSession状态:{}", saneSession != null); + if (saneSession == null) { + synchronized(lock){ + if (saneSession == null) { + log.info("jFreeSaneConfig:" + JSON.toJSONString(remoteConfig)); + InetAddress address = InetAddress.getByName(remoteConfig.getIp()); + saneSession = SaneSession.withRemoteSane(address); + log.info("初始化saneSession完成,状态:{}", saneSession != null); + } + } + } + return saneSession; + } + + /** + * 关闭SaneSession对象,如果对象不为null + */ + public static void closeSaneSession() { + if (saneSession != null) { + try { + saneSession.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + saneSession = null; + } + } + + /** + * 获取所有的SANE驱动器设备列表 + * + * @return SANE驱动器设备列表 + * @throws IOException 如果在通信中发生I/O错误 + * @throws SaneException 如果在与SANE交互中发生错误 + */ + public static List getSaneDrivers() throws IOException, SaneException { + return getSaneSession().listDevices(); + } + + + /** + * 设置Sane设备 + * @param name 设备名称 + * @return 设备对象 + * @throws IOException 输入/输出异常 + * @throws SaneException Sane异常 + */ + public static SaneDevice setSaneDevice(String name) throws IOException, SaneException { + if (saneDevice == null || !saneDevice.getName().equals(name)) { + if (saneDevice != null && saneDevice.isOpen()) { + // 关闭当前在使用的SANE设备 + saneDevice.close(); + } + saneDevice = saneSession + .listDevices().stream().filter(s -> name.equals(s.getName())).findFirst().orElse(null); + } + return saneDevice; + } + + /** + * 获取Sane设备(如果不存在则返回null) + * @return Sane设备 + */ + public static SaneDevice getDevice() { + return saneDevice; + } + + /** + * 获取指定名称的Sane设备,如果设备不存在则返回null + * @param name 设备名称 + * @return 指定名称的Sane设备 + * @throws RuntimeException 运行时异常 + */ + public static SaneDevice getDevice(String name) { + try { + return setSaneDevice(name); + } catch (IOException | SaneException e) { + throw new RuntimeException(e); + } + } + + + /** + * 获取一个正常的文件 + * 打开Sane设备 + * 通过Sane设备获取图像 + * 创建或更新最后访问时间的文件 + * 将图像写入文件 + * 返回文件 + * @throws RuntimeException - 如果发生I/O错误 + */ + public static File getSaneFile() throws IOException { + try { + saneDevice.open(); + BufferedImage bufferedImage = saneDevice.acquireImage(); + File file = FileUtil.createTempFile("sane","png",true); + ImageIO.write(bufferedImage, "png", file); + return file; + } catch (IOException | SaneException e) { + throw new RuntimeException(e); + }finally { + if(saneDevice != null){ + saneDevice.close(); + } + } + } + + /** + * 释放资源 + */ + public static void resource(){ + try { + if(saneDevice != null){ + closeSaneDevice(); + } + if(saneSession != null){ + closeSaneSession(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * 关闭Sane设备 + */ + public static void closeSaneDevice() throws IOException { + if(saneDevice != null){ + try { + saneDevice.close(); + } catch (IOException e) { + throw new IOException(e); + } + saneDevice = null; + } + + } + +} + diff --git a/src/main/java/org/aohe/core/sane/utils/SystemUtils.java b/src/main/java/org/aohe/core/sane/utils/SystemUtils.java new file mode 100644 index 0000000..5cb6ca0 --- /dev/null +++ b/src/main/java/org/aohe/core/sane/utils/SystemUtils.java @@ -0,0 +1,48 @@ +package org.aohe.core.sane.utils; + +public class SystemUtils { + + /** + * 判断操作系统是否是 Windows + * + * @return true:操作系统是 Windows + * false:其它操作系统 + */ + public static boolean isWindows() { + String osName = getOsName(); + + return osName != null && osName.startsWith("Windows"); + } + + /** + * 判断操作系统是否是 MacOS + * + * @return true:操作系统是 MacOS + * false:其它操作系统 + */ + public static boolean isMacOs() { + String osName = getOsName(); + + return osName != null && osName.startsWith("Mac"); + } + + /** + * 判断操作系统是否是 Linux + * + * @return true:操作系统是 Linux + * false:其它操作系统 + */ + public static boolean isLinux() { + String osName = getOsName(); + + return (osName != null && osName.startsWith("Linux")) || (!isWindows() && !isMacOs()); + } + + /** + * 获取操作系统名称 + * @return os.name 属性值 + */ + public static String getOsName() { + return System.getProperty("os.name"); + } +} \ No newline at end of file