JAVA服务端实现页面截屏(附代码)

这篇具有很好参考价值的文章主要介绍了JAVA服务端实现页面截屏(附代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

适配需求

  1. 有正确完整的地址url;
  2. 通过浏览器能打开该url对应页面;
  3. 需要后台可以自动‘截屏’该页面;
  4. ‘截屏’后的页面可以输出文件(如pdf、png)格式;

方案一、使用JxBrowser

简介 :JxBrowser 具有多进程架构。 它在独立的本地进程中运行 Chromium,这些进程通过进程间通信 (IPC) 通道以光速与 Java 进行通信。 如果 Chromium 中出现错误,您的 Java 进程将保持活动状态。 这一切都与良好的用户体验和用户数据安全有关。​

架构逻辑如下
javafx 截图,Java,开发工具,java,chrome,前端,pdf

使用步骤:

  1. 先申请获得30天免费使用秘钥,也可以直接付费地址
  2. 获取 支持的Jar 包:
  3. Coding :
import static com.teamdev.jxbrowser.engine.RenderingMode.OFF_SCREEN;
import static com.teamdev.jxbrowser.print.PaperSize.ISO_A4;

import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.PrintCallback;
import com.teamdev.jxbrowser.browser.callback.PrintHtmlCallback;
import com.teamdev.jxbrowser.browser.callback.SaveAsPdfCallback;
import com.teamdev.jxbrowser.browser.event.PrintPreviewOpened;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.frame.Frame;
import com.teamdev.jxbrowser.print.PdfPrinter;
import com.teamdev.jxbrowser.print.PrintJob;
import com.teamdev.jxbrowser.print.event.PrintCompleted;
import java.nio.file.Path;
import java.nio.file.Paths;

public class JxBrowserDemo {
    // 构造一个浏览器实例
    public JxBrowserDemo() {
        // 设置证书秘钥
        System.setProperty("jxbrowser.license.key", "此处略");
    }
    // 执行方法
    public void run(String url) {
        EngineOptions engineOptions = EngineOptions.newBuilder(OFF_SCREEN).build();
        // 初始化 Chromium 引擎
        Engine engine = Engine.newInstance(engineOptions);
        // 创建一个浏览器实例
        Browser browser = engine.newBrowser();
        // 等待加载url完成
        browser.navigation().loadUrlAndWait(url);
        // 打印网络页面
        browser.mainFrame().ifPresent(frame -> System.out.println(frame.html()));
        browser.set(PrintCallback.class, (params, tell) -> {
            tell.print();
        });
        // 设置pdf文件导出位置
        browser.set(PrintHtmlCallback.class, (params, tell) -> {
            Path path = Paths.get("/Users/*****/temp3.pdf");
            PdfPrinter<PdfPrinter.HtmlSettings> printer = params.printers().pdfPrinter();
            PrintJob<PdfPrinter.HtmlSettings> printJob = printer.printJob();
            printJob.settings()
                    .paperSize(ISO_A4)
                    .enablePrintingBackgrounds()
                    .pdfFilePath(path)
                    .apply();
            printJob.on(PrintCompleted.class, event -> {
                if (event.isSuccess()) {
                    System.out.println("Printing is completed successfully.");
                } else {
                    System.out.println("Printing has failed.");
                }
            });
            tell.proceed(printer);
        });
        browser.mainFrame().ifPresent(frame -> {
            frame.print();
        });
        try {
            Thread.sleep(100000);
        }catch (InterruptedException e) {
            // do nothing
        }
        // 关闭引擎释放资源
        engine.close();
    }
}

方案二、JavaFX WebView

JavaFX WebView 是在 2014 年成为 JDK 8 的一部分的 JavaFX 2.0 中引入的。
如果您使用 Java 8,那么您不需要做任何特别的事情来开始使用 JavaFX WebView。
使用JDK 11及更高版本的JavaFX不再捆绑,因此要使用JavaFX 11或更高版本进行开发,您必须单独下载。

JavaFX在您的Java进程中初始化并运行WebKit。JavaFX允许您非常快速地创建和显示WebView。
然而WebKit会分配和使用Java进程的内存和CPU,一些现代网页可能会分配超过1GB的RAM。
您创建和加载网页的WebView实例越多,Java应用程序的RAM就越多(耗内存)。
javafx 截图,Java,开发工具,java,chrome,前端,pdf

使用步骤:

不需要额外操作直接coding即可
Coding :

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;

// 需要继承 javafx.application.Application
public class JavaFxDemo extends Application {
    private Scene scene;
    @Override
    public void start(Stage stage) throws Exception {
        // 创建画布
        stage.setTitle("Web View");
        // 设置场景
        scene = new Scene(new Browser(), 750, 500, Color.web("#666970"));
        stage.setScene(scene);
        // 风格样式
        scene.getStylesheets().add("webviewsample/BrowserToolbar.css");
        stage.show();
    }
}
// 需要继承 Region
class Browser extends Region {
    final WebView browser = new WebView();
    // 浏览器引擎
    final WebEngine webEngine = browser.getEngine();
    public Browser() {
        // 浏览器应用风格
        getStyleClass().add("browser");
        // 加载web页面
        webEngine.load("http://www.oracle.com/products/index.html");
        // 页面增加到引擎中
        getChildren().add(browser);

    }
    private Node createSpacer() {
        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);
        return spacer;
    }
    @Override protected void layoutChildren() {
        double w = getWidth();
        double h = getHeight();
        layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);
    }
    @Override protected double computePrefWidth(double height) {
        return 750;
    }
    @Override protected double computePrefHeight(double width) {
        return 500;
    }
}

public class Application {
    public static void main(String[] args) {
        System.out.println("hello, world");
        javaFxDemo.run("https://www.baidu.com");
    }
}

方案三、Headless Chrome

简介:Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序。

原理: 通过chromedriver 驱动加载对应页面,可以后台获取截图,并按照文件、字节流等方式返回;

使用步骤:

  1. 下载 chromedriver 和 同版本 的 chrome 到本地 驱动地址;
  2. 放置到系统对应位置(win系统在Windows目录下,Mac在包含bin的目录下),设置好执行权限;
  3. 引入 selenium-server-standalone.jar 依赖
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.6.0</version>
</dependency>
  1. Coding :
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;

@Service
public class ScreenshotService {

    private static WebDriver driver;
    @PostConstruct
    private void initDriver(){
        ChromeOptions options = new ChromeOptions();
        /*
         * 这里是设置要执行的命令
         * --headless: 不提供可视化页面(无头模式)
         * --disable-gpu: 禁用GPU加速
         * --window-size: 修改截图页面的尺寸 "--window-size=1920,1200"
         * --ignore-certificate-errors:
         */
        options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1920", "--ignore-certificate-errors");
        options.addArguments("--disable-dev-shm-usage", "--no-sandbox");
        driver = new ChromeDriver(options);
    }

    /**
     * 根据网络url获取网络截屏的字节数组
     * @param url 网络url
     * @return 字节数组
     */
    private static synchronized byte[] getFileByteArry(String url){
        // 1.打印chromedriver驱动
        log.info("[页面抓取]- {}", driver);
        long startTime = System.currentTimeMillis();
        // 2.加载web页面
        driver.get(url);
        // 3.页面等待渲染时长,如果你的页面需要动态渲染数据的话一定要留出页面渲染的时间,单位默认是秒
        new WebDriverWait(driver, 5);
        // 4.获取到截图的文件字节
        byte[] byteArry = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
        log.info("[页面抓取]ChromeDriver处理结束用时{}s, Title:{}", calUsedTime(startTime), driver.getTitle());
        return byteArry;
    }
}

【开发过程中我实际遇到的问题】:
1.代码指定浏览器驱动位置无效, 生成驱动时按照系统自动加载:win系统在Windows目录下,Mac在包含bin的目录下;
2.Mac系统中驱动需要权限,Win不需要可权限可直接执行;
3.页面大小设置问题:不提供可视化页面情况下必须指定截图页面尺寸,自上而下自左而右截取(可能有丢失内容风险);
4.如果设置页面渲染超时间(可以去除该设置):默认需要指定加载到页面Element标签ID,如果页面不含该ID则报错;


综上方案对比

JxBrowser JavaFX Headless
开源 否,需付费
依赖 第三方包 JDK selenium +谷歌驱动
操作 复杂,需要申请令牌和增加依赖 简单 复杂,下载安装驱动和浏览器并增加依赖
代码复杂度 简单,依赖包强大 稍复杂,需要有抽象和分层概念 简单,面向对象概念
耗时 快 2-3秒 一般 3-5秒 慢 4-6秒
页面效果 nice 一般 nice
不足 依赖第三方服务 无法后台存储,需要弹窗选择 执行稍慢

记录我的一个失败方案

思路:通过get请求url获得一个html响应,将html打印获取页面;
失败原因:html需要在线获取一些前端样式(js、css)渲染,如果直接打印可能只是一个空页面。必须要经过web端进行渲染才能实现基本的页面格式。


参考

文章为个人实际开发完成后的技术整理
有相关问题可以参考我当时查资料的参考(帮您节省时间),如下:

JxBrowser
知乎 · 什么是 JxBrowser
JavaFX入门介绍
知乎 · JxBrowser还是JavaFX WebView
CSDN · Headless Chrome
CSDN · 使用ChromeHeadLess文章来源地址https://www.toymoban.com/news/detail-760635.html

到了这里,关于JAVA服务端实现页面截屏(附代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 详解Java实现2048小游戏(JavaFX,完整源码+注释说明)

    刚刚完成的一个小游戏,写文章记录一下,如果有任何错误或者可以改进的代码请提出 另一方面也是方便自己几个月或几年后忘记时,来这里翻一翻回顾思路 目录 基本界面: 类的组织: _CardPane: _CardMatrixPane: _CardColor: _GameMenuBar: _2048Demo: 基本思路: 卡片: 卡片矩阵:

    2024年02月03日
    浏览(51)
  • 【Selenium+Webmagic】基于JAVA语言实现爬取js渲染后的页面,附有代码

    事先声明 笔者最近需要查看一些数据,自己挨个找太麻烦了,于是简单的学了一下爬虫。笔者在这里声明, 爬的数据只为学术用 ,没有其他用途,希望来这篇文章学习的同学能抱有同样的目的。 枪本身不坏,坏的是使用枪的人 效果 查看自己的Chrome版本,过高需要卸载再下

    2024年02月04日
    浏览(56)
  • Java 成功实现通过网址URL截图保存

    实操 DjNativeSwing 方式 的现象 1.截图效果(非百度网页):有图片,排版正常,但是部分样式丢失(输入框的文字掉下去了) 2.main 方法使用的里面没问题 ,但是springboot项目去启动以后,该方式触发报错 需要在启动类,关闭无头模式 3.本地项目成功实现以后 部署linux系统后,

    2024年02月13日
    浏览(44)
  • 无头模式下selenium实现长截图(Java版本)

    无头模式下使用selenium截图时经常遇到有滚动条的界面内容截不全的问题,通过各种渠道找到了解决方案,现记录如下

    2024年02月12日
    浏览(56)
  • chromedriver+Selenium+springboot+Java实现后端截图

    chromedriver这种方法实现截图,依赖服务器端的谷歌浏览器软件,需要在服务器端下载谷歌浏览器。 Windows服务器说明 1.下载谷歌浏览器 2.根据第一步下载的谷歌浏览器版本,下载chromedriver,可以在这个页面找到和版本相近的版本去下载https://googlechromelabs.github.io/chrome-for-testin

    2024年01月21日
    浏览(53)
  • 微信小程序在某个页面防止用户截屏、录屏实现

    好吧!好吧!项目~又来搞事情了,想在预览图片的时候监听图片长按菜单的“保存图片”操作,因为在这有个查询用户是否有保存图片的权限,没有的话就不能把图片保存到手机,但是查了半天,发现根本无法监听到长按菜单的对应操作(分享朋友、保存图片等等),干脆把

    2024年02月05日
    浏览(350)
  • 使用javafx实现的基于udp、tcp的聊天GUI应用,可用作Java大作业、计网课程设计+视频演示

    点击这里下载源码 项目使用javafx作为ui开发平台,基于udp和tcp实现聊天功能。 支持同一网络环境内多设备聊天(测试了多台windows、mac设备通过有线和无线连接到一个局域网的情况)。 通信的流程可以简单描述为: 每个用户登录时会生成一个带uuid的用户信息 使用udp向局域网

    2024年02月04日
    浏览(45)
  • 电脑如何使用QQ进行长截图(解决无效区域无法长截屏问题)

    在工作生活中,我们经常需要用电脑进行截图。很多不熟悉电脑使用的小伙伴不知道怎么进行截屏。对此我在这里提供以下几个使用电脑快捷键截屏的好办法(仅本人经常使用,亲测有效的办法): 1、win+shift+s快捷键: 可以看见第一个是矩形截屏,可以截下当前屏幕比较方

    2024年02月09日
    浏览(47)
  • Java模拟OPC Server服务器并创建节点代码实现

    模拟OPC Server服务器的方法除了使用KEPServerEX6软件以外,还可以使用java代码模拟启动一个opc server。下文详细讲解,如何使用java代码,实现模拟一个或者多个opc server服务器。 OPC(OLE for Process Control)Server是一种用于实时数据通信的标准化软件接口,它允许不同厂商的设备和软

    2024年02月09日
    浏览(45)
  • Java的Swing被JavaFX取代了

    JavaFX是Oracle在Java平台上推出的一种富客户端应用程序开发框架,它在功能和外观方面更加先进和强大,逐渐取代了过时的Swing框架。JavaFX提供了丰富的用户界面控件、布局容器、图形绘制、媒体播放和动画等功能,使得开发者能够更加轻松地构建现代化、交互式的桌面应用程

    2024年02月04日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包