• Monthly Archives: 3月 2024

在SpringBoot项目中使用AWT的Toolkit.getDefaultToolkit().getScreenSize()时出现Exception in thread “JavaFX Application Thread” java.awt.HeadlessException错误

可以修改启动类为:

@SpringBootApplication
public class RmToolApplication implements CommandLineRunner {

	public static void main(String[] args) {
		//SpringApplication.run(RmToolApplication.class, args);
		SpringApplicationBuilder builder = new SpringApplicationBuilder(RmToolApplication.class);
		builder.headless(false).run(args);
	}

	@Override
	public void run(String... args) throws Exception {
		Application.launch(MainApp.class, args);
	}

}

SpringBoot项目使用tesseract

官方github地址:

https://github.com/tesseract-ocr/tesseract

注意,tess4j中用到的JAI类库只支持以下图像类型:

详情可到进入下面链接查看:

https://github.com/jai-imageio/jai-imageio-core

安装系统环境(可选)

https://github.com/UB-Mannheim/tesseract/wiki

如果不安装,则会在执行OCR识别时出现如下作物提示:

java.lang.RuntimeException: Unsupported image format. May need to install JAI Image I/O package.
https://github.com/jai-imageio/jai-imageio-core
	at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:215) ~[tess4j-4.5.5.jar:4.5.5]
	at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:195) ~[tess4j-4.5.5.jar:4.5.5]

下载语言数据

https://github.com/tesseract-ocr/tessdata

到这个连接中,下载zip包:

做OCR识别之前,不配置tessdata的话,会出现以下错误:

当然,你也可以只下载eng.traineddata

引入依赖

//OCR依赖
implementation 'net.sourceforge.tess4j:tess4j:4.5.5'

//JAI Image I/O 扩展库
implementation group: 'com.github.jai-imageio', name: 'jai-imageio-jpeg2000', version: '1.4.0'

代码示例

        File ocrFile = new File("ocr.png ");
        //使用OCR提取图片文字
        Tesseract tesseract = new Tesseract();
        //设置 Tesseract 数据文件的路径,如果不是默认路径的话
        //tesseract.setDatapath("path_to_your_tessdata_folder");
        try {
            String result = tesseract.doOCR(ocrFile);
            System.out.println(result);
        } catch (TesseractException e) {
            System.err.println(e.getMessage());
        }

其他

java.lang.RuntimeException: Unsupported image format. May need to install JAI Image I/O package.
https://github.com/jai-imageio/jai-imageio-core
	at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:215) ~[tess4j-4.5.5.jar:4.5.5]
	at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:195) ~[tess4j-4.5.5.jar:4.5.5]

出现这种情况,请注意一下是否你的图像类型不属于支持的范围,请查看JAI的官网链接,别怀疑,PNG和JPG都是不支持的~!

SpringBoot下使用OpenCV的MatchTemplate功能

在Windows下编译OpenCV(如在其他系统下编译,请自行搜索)

CMake:

https://cmake.org/download/

  1. 下载zip版本“cmake-3.xx-win64-x64.zip”
  2. 解压到指定目录并添加bin所在目录到环境变量。
  3. 在终端输入“cmake –help”或 “cmake –version”查看是否配置成功。

MinGW:

https://sourceforge.net/projects/mingw-w64/files/

  1. 推荐下载 离线版本“x86_64-posix-seh”
  2. 解压到指定目录并将bin目录加入到环境变量
  3. 在终端输入 “gcc –version”。查看是否安装成功。

OpenCV

本次 Windows 环境的安装,因此下载OpenCV-4.6.0 Windows 版。

双击下载好的exe文件,程序会生成 opencv 文件夹。

这个 opencv 文件夹就是我们后面的编译源文件。

新建一个文件夹 build_for_vscode ,用于存放我们后面的编译结果。

下载OpenCV运行库

下载OpenCV – 4.7.0的Windows版本,运行并制定解压目录。

(注意,如果这里选择其他版本,请务必在后面的项目依赖用也配置对应的4.7.0版本。)

然后配置系统的环境变量Path,添加“opencv/build/java/x86/opencv_java470.dll”。

否则会报类似如下的错误:

Exception in thread "JavaFX Application Thread" java.lang.UnsatisfiedLinkError: no opencv_java470 in java.library.path: D:\Java\jdk-17.0.8\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\Program Files\Git\cmd;C:\Program Files\TortoiseGit\bin;C:\Program Files (x86)\Microsoft SQL Server\160\Tools\Binn\;C:\Program Files\Microsoft SQL Server\160\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files\Microsoft SQL Server\160\DTS\Binn\;C:\Program Files\Docker\Docker\resources\bin;D:\Java\jdk-1.8\bin;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2\plugins\maven\lib\maven3\bin;C:\Program Files\nodejs\;C:\Windows\System32\Wbem;D:\Redis-x64-3.2.100;C:\Program Files\Go\bin;C:\Program Files\Go\bin;C:\Program Files\OpenSSL-Win64\bin;D:\MinGW-12.2.0\bin;D:\gradle-8.5\bin;D:\hkbea\20231201.PBWMS Enhancement\RmTool\opencv\build\java\x64;C:\Program Files\Tesseract-OCR;C:\Users\cp0612\AppData\Local\Microsoft\WindowsApps;C:\Users\cp0612\AppData\Roaming\npm;C:\Windows\System32\Wbem;C:\Users\cp0612\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\cp0612\go\bin;C:\Program Files\CMake\bin;.
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2429)
	at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:818)
	at java.base/java.lang.System.loadLibrary(System.java:1989)
	at com.hkbea.pbwms.rmtool.MainApp$1.run(MainApp.java:151)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run$$$capture(InvokeLaterDispatcher.java:96)
	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java)
	at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
	at java.base/java.lang.Thread.run(Thread.java:833)

在项目中引入依赖

依赖版本可以查看这里:https://mvnrepository.com/artifact/org.bytedeco/opencv

	// https://mvnrepository.com/artifact/org.bytedeco/opencv
	implementation group: 'org.bytedeco', name: 'opencv', version: '4.7.0-1.5.9'

请务必注意version需要和所下载的OpenCV运行版本号一致。

示例代码

// 加载OpenCV库
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

// 读取源图像和模板图像
Mat sourceImage = Imgcodecs.imread("screenshot.png");
Mat templateImage = Imgcodecs.imread("template.png");

// 创建结果矩阵
int resultCols = sourceImage.cols() - templateImage.cols() + 1;
int resultRows = sourceImage.rows() - templateImage.rows() + 1;
//Mat resultImage = new Mat(resultRows, resultCols, CvType.CV_32F);
Mat resultImage = new Mat(resultRows, resultCols, CvType.CV_32FC1);

// 执行模板匹配
// 注意:这里只是一个简单的示例,实际的模板匹配需要根据具体需求进行参数调整和处理
/**
 * result 参数:用于存储匹配结果的矩阵,您可以检查这个矩阵来了解匹配的情况。
 * method 参数:指定匹配方法。常见的匹配方法包括 Imgproc.TM_SQDIFF、 Imgproc.TM_SQDIFF_NORMED、Imgproc.TM_CCORR、Imgproc.TM_CCORR_NORMED、Imgproc.TM_CCOEFF 和 Imgproc.TM_CCOEFF_NORMED,它们会影响到匹配结果的精确度和准确度。
 * mask 参数:指定模板的掩码,可以使用它来限制匹配区域,提高匹配的准确度。
 * scale 和 scaleFactor 参数:指定搜索图像和模板图像的缩放比例,可以通过调整这些参数来适应不同尺寸的图像。
 */
Imgproc.matchTemplate(sourceImage, templateImage, resultImage, Imgproc.TM_CCOEFF_NORMED);

// --------- 处理匹配结果 ----------

//匹配阈值处理
//double thresholdValue = 0.8;
//Core.compare(resultImage, new Scalar(thresholdValue), resultImage, Core.CMP_GE);

// 寻找最大和最小匹配值及其位置
Core.MinMaxLocResult mmr = Core.minMaxLoc(resultImage);

//比对匹配到的图像结果
double threshold = 0.2; // 设置匹配阈值
if (mmr.maxVal >= threshold) {
    //log.info("匹配成功");
    System.out.println("匹配成功");
    Point maxLoc = mmr.maxLoc;
    // 在原始图像中画出匹配结果的矩形框
    Rect matchRect = new Rect((int)maxLoc.x, (int)maxLoc.y, templateImage.cols(), templateImage.rows());
    Imgproc.rectangle(sourceImage, matchRect.tl(), matchRect.br(), new Scalar(0, 255, 0), 2);

    // 将 Mat 对象转换为 BufferedImage
    //imageView.setImage(SwingFXUtils.toFXImage(matToBufferedImage(resultImage),null));
    BufferedImage resultBuffImage = Mat2BufImg(sourceImage,".png");
    WritableImage rersultWritableImage = SwingFXUtils.toFXImage(resultBuffImage,null);
    File resultImageFile = new File("outputImage.png");
    try {
        ImageIO.write(SwingFXUtils.fromFXImage(rersultWritableImage, null), "png", resultImageFile);
        System.out.println("屏幕截图已保存到: " + resultImageFile.getAbsolutePath()+"; 大小="+resultImageFile.length());
    } catch (IOException e) {
        System.out.println("无法保存屏幕截图: " + e.getMessage());
    }
    imageView.setImage(rersultWritableImage);
} else {
    // 未找到匹配
    //log.info("匹配失败");
    System.out.println("匹配失败");
}

// 释放资源
sourceImage.release();
templateImage.release();
resultImage.release();
close