Java实现url页面截图功能(windows)
Java实现url页面截图功能~目前实现了windows、linux(centos7)版本,谷歌浏览器需要下载90.x版本,目前暂时没找到安装包
代码
package com.ruoyi.school.util;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class ChromeScreenshotUtil {
private static final String CHROME_PATH = "C:/Program Files/Google/Chrome/Application/chrome.exe";
private static final String TEMP_SCREENSHOT_DIR = "D:/project/uploadFile";
static {
// 初始化检查
File chromeFile = new File(CHROME_PATH);
if (!chromeFile.exists()) {
throw new RuntimeException("Chrome未找到:" + CHROME_PATH);
}
File dir = new File(TEMP_SCREENSHOT_DIR);
if (!dir.exists() && !dir.mkdirs()) {
throw new RuntimeException("无法创建临时目录:" + TEMP_SCREENSHOT_DIR);
}
}
public String captureScreenshotAsBase64(String url) throws IOException, InterruptedException {
return captureScreenshotAsBase64(url, 1200, 2000, 10000);
}
public String captureScreenshotAsBase64(String url, int width, int height, int delay) throws IOException, InterruptedException {
String fileName = "temp_screenshot_" + System.currentTimeMillis() + ".png";
File tempFile = new File(TEMP_SCREENSHOT_DIR, fileName);
String outputPath = tempFile.getAbsolutePath();
try {
// 执行Chrome截图(省略,同之前)
ProcessBuilder processBuilder = new ProcessBuilder(
CHROME_PATH,
"--headless",
"--disable-gpu",
"--no-sandbox",
"--window-size=" + width + "," + height,
"--virtual-time-budget=" + delay,
"--screenshot=" + outputPath,
url
);
processBuilder.directory(new File(CHROME_PATH).getParentFile());
Process process = processBuilder.start();
captureStream(process.getInputStream(), "输出");
captureStream(process.getErrorStream(), "错误");
int exitCode = process.waitFor(60, java.util.concurrent.TimeUnit.SECONDS) ? process.exitValue() : -1;
if (exitCode != 0) {
throw new RuntimeException("Chrome退出码:" + exitCode);
}
// 等待文件生成
int retryCount = 0;
while (retryCount < 5) {
if (tempFile.exists() && tempFile.length() > 0) {
Thread.sleep(2000);
break;
}
Thread.sleep(1000);
retryCount++;
}
if (retryCount >= 5 || !tempFile.exists() || tempFile.length() == 0) {
throw new RuntimeException("图片未生成:" + outputPath);
}
// 关键:读取字节并验证
byte[] imageBytes = readFileToBytes(tempFile);
// 验证PNG头(前8字节必须为89 50 4E 47 0D 0A 1A 0A)
if (imageBytes.length < 8) {
throw new RuntimeException("字节数组过短,不是有效的PNG");
}
byte[] pngHeader = new byte[]{(byte)0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
for (int i = 0; i < 8; i++) {
if (imageBytes[i] != pngHeader[i]) {
throw new RuntimeException("PNG头验证失败,第" + i + "字节应为" + String.format("%02X", pngHeader[i]) + ",实际为" + String.format("%02X", imageBytes[i]));
}
}
// 生成Base64
String base64Str = Base64.getEncoder().encodeToString(imageBytes);
String result = "data:image/png;base64," + base64Str;
return result;
} finally {
// 保留文件用于手动验证
tempFile.delete();
}
}
// 循环读取字节,确保完整
private byte[] readFileToBytes(File file) throws IOException {
if (!file.exists()) {
throw new FileNotFoundException("文件不存在:" + file.getAbsolutePath());
}
if (file.length() == 0) {
throw new IOException("文件为空");
}
try (InputStream is = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
byte[] result = bos.toByteArray();
if (result.length != file.length()) {
throw new IOException("读取不完整:文件大小=" + file.length() + ",读取大小=" + result.length);
}
return result;
}
}
private void captureStream(InputStream is, String type) {
new Thread(() -> {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println("[Chrome" + type + "] " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
public static void main(String[] args) {
try {
String url = "http://192.168.110.175:8083/#/";
String base64 = new ChromeScreenshotUtil().captureScreenshotAsBase64(url);
System.out.println(base64);
} catch (Exception e) {
e.printStackTrace();
}
}
}
本文来自博客园,作者:青喺半掩眉砂,转载请注明原文链接:https://www.cnblogs.com/xiaoguo-java/p/19051281

浙公网安备 33010602011771号