使用wkhtmltoimage实现生成长图分享

需求

用户可以选择以长图的形式分享本网页

方法

  • wkhtmltopdf
    • wkhtmltopdf url file
    • wkhtmltoimage url file
  • java
    • Runtime.getRuntime().exec()

下载

直接去官网下载对应的版本:官网

命令行使用WK

>  wkhtmltopdf https://www.nowcoder.com /opt/project/java/mycommunity-pdfs/1.pdf            
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done>  wkhtmltoimage  https://www.nowcoder.com /opt/project/java/mycommunity-images/1.png     
Loading page (1/2)
Rendering (2/2)
Done// 上面那条命令生成的长图太大了,可以使用下面这条:以75%的质量输出
>  wkhtmltoimage --quality 75  https://www.nowcoder.com /opt/project/java/mycommunity-images/1.png     
Loading page (1/2)
Rendering (2/2)
Done

在java中调用

application.properties:

mycommunity.path.domain=http://localhost:8080
server.servlet.context-path=/myCommunity
# WK
wk.image.command=/usr/local/bin/wkhtmltoimage
wk.image.storage=/opt/project/java/mycommunity-images/

WK配置类,在每次程序开始运行时自动生成存放图像的文件夹

@Configuration
public class WkConfig {private static final Logger logger = LoggerFactory.getLogger(WkConfig.class);@Value("${wk.image.storage}")private String wkImageStorage;@PostConstructpublic void init(){// create the dic about WKimageFile file = new File(wkImageStorage);if(!file.exists()){file.mkdir();logger.info("create the dictionary of WKimage: " + wkImageStorage);}}
}

调用WK的控制层,因为生成长图比较耗时,所以使用异步操作,在用户操作时调用Kafka的生产者生成事件,通知消费者:

@Controller
public class ShareController implements CommunityConstant {private static final Logger logger = LoggerFactory.getLogger(ShareController.class);@Autowiredprivate EventProducer eventProducer;@Value("${mycommunity.path.domain}")private String domain;@Value("${server.servlet.context-path}")private String contextPath;@Value("${wk.image.storage}")private String wkImageStorage;@GetMapping(path = "/share")@ResponseBodypublic String share(String htmlUrl){// generate the file nameString fileName = CommunityUtil.generateUUID();// Asynchronous generation long picEvent event = new Event().setTopic(TOPIC_SHARE).setData("htmlUrl", htmlUrl).setData("fileName", fileName).setData("suffix", ".png");eventProducer.fireEvent(event);Map<String, Object> map = new HashMap<>();map.put("shareUrl", domain + contextPath + "/share/image" + fileName);return CommunityUtil.getJSONString(0, null, map);}//@GetMapping(path = "/share/image/{fileName}")public void getShareImage(@PathVariable("fileName") String fileName, HttpServletResponse response){if(StringUtils.isBlank(fileName)){throw new IllegalStateException("the file name cannot be blank");}response.setContentType("image/png");File file = new File(wkImageStorage + "/" + fileName + ".png");try {OutputStream os = response.getOutputStream();FileInputStream fis = new FileInputStream(file);byte[] data = new byte[1024];int len = 0;while ((len = fis.read(data)) != -1) {os.write(data, 0, len);}} catch (IOException e) {logger.error("querty the long image failed: ", e.getMessage());}}
}

Kafka的消费者,定义如何消费生成长图的事件:

@Component
public class EventConsumer implements CommunityConstant {@Autowiredprivate static final Logger logger = LoggerFactory.getLogger(EventConsumer.class);@Value("${wk.image.storage}")private String wkImageStorage;@Value("${wk.image.command}")private String wkImageCommand;@KafkaListener(topics = {TOPIC_SHARE})public void handleShareMessage(ConsumerRecord record) {if (record == null || record.value() == null) {logger.error("the content of the message is empty");return;}Event event = JSONObject.parseObject(record.value().toString(), Event.class);if (event == null) {logger.error("message format error");return;}String htmlUrl = (String) event.getData().get("htmlUrl");String fileName = (String) event.getData().get("fileName");String suffix = (String) event.getData().get("suffix");String cmd = wkImageCommand + " --quality 75 " + htmlUrl + " " + wkImageStorage + "/" + fileName + suffix;try {Runtime.getRuntime().exec(cmd);logger.info("generate long image successfully: " + cmd);} catch (IOException e) {logger.info("generate long image fail: " + e.getMessage());}}
}

测试

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/73079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis高可用——主从复制、哨兵模式、cluster集群

1、redis群集有三种模式 分别是主从同步/复制、哨兵模式、Cluster&#xff0c;下面会讲解一下三种模式的工作方式&#xff0c;以及如何搭建cIustr群集 主从复制:主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的…

功能测试常用的测试用例大全

登录、添加、删除、查询模块是我们经常遇到的&#xff0c;这些模块的测试点该如何考虑 1)登录 ① 用户名和密码都符合要求(格式上的要求) ② 用户名和密码都不符合要求(格式上的要求) ③ 用户名符合要求&#xff0c;密码不符合要求(格式上的要求) ④ 密码符合要求&#xff0c;…

stm32 freeRTOS lwip TCP快速发送,内存泄露问题

现象1&#xff1a; 发送缓慢&#xff0c;tcp_write之后要等200多ms才能过发送出去&#xff0c;而且粘包严重。 解决办法 tcp_write之后&#xff0c;立马调用tcp_output &#xff0c;tcp就会立马发送。 tcp_write tcp_output 现象2&#xff1a; 持续快速发送和接受TCP数据出…

WireShark抓包工具的安装

1.下载安装包 在官网或者电脑应用商城都可以下载 2.安装 打开安装包&#xff0c;点击next 点击next 选择UI界面&#xff0c;两种都装上 根据习惯选择 选择安装位置点击安装 开始安装安装成功

CMake+CLion+Qt配置

在这里我下载MSVC的工具包&#xff0c;并没有下载Visual Studio。 配置编译环境 下载Visual Studio&#xff0c;其中有MSVC编译工具&#xff0c;下载MSVC工具包&#xff0c; 工具包下载链接&#xff1a;https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/ …

docker - 在 alpine 上安装 MongoDB 的问题

RUN echo http://dl-cdn.alpinelinux.org/alpine/v3.6/community >> /etc/apk/repositories RUN apk update RUN apk add mongodb3.4.4-r0RUN mongo --version错误 ERROR: unsatisfiable constraints: so:libboost_chrono-mt.so.1.62.0 (missing): required by: mongodb-…

Jabbi的Rust学习日记(一)

Rust环境安装 Windows:Install Rust - Rust Programming Language (rust-lang.org) 访问网页&#xff0c;下载64bit | 32bit 版本 下载完成后打开&#xff0c;直接enter即可 Linux:输入指令 curl https://sh.rustup.rs-sSf | sh 我会报错&#xff0c;好像是链接不到这个网址&a…

SQL Server 跨库/服务器查询

这里写目录标题 1 SQL Server 跨库/服务器查询1.1 跨库查询1.2 跨服务器查询1.2.1 创建链接服务器1.2.2 跨库查询 1.3 拓展&#xff1a;SQL Server 中所有权和用户与架构的分离 1 SQL Server 跨库/服务器查询 1.1 跨库查询 在同一服务器下的跨库查询较为简单&#xff0c;示例…

git stash命令的用法

在Git中&#xff0c;stash命令是最常用的命令之一。它可以在你提交之前&#xff0c;暂时地保存你的工作现场&#xff0c;并将其记录在Git的堆栈中。当你再次回来完成该工作时&#xff0c;你可以简单地弹出该堆栈&#xff0c;并重新开始未完成的工作。 0. git stash 该命令将当…

macOS Ventura 13.5.2(22G91)发布,附黑/白苹果镜像下载地址

系统介绍&#xff08;下载请百度搜索&#xff1a;黑果魏叔&#xff09; 黑果魏叔 9 月 8 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.5.2 更新&#xff08;内部版本号&#xff1a;22G91&#xff09;&#xff0c;本次更新距离上次发布隔了 21 天。 本次更新查…

6.Flask-APScheduler定时任务框架

1.下载安装 pip install flask-apscheduler2.基本使用 from flask import Flask from flask_apscheduler import APScheduler app Flask(__name__) aps APScheduler() # 配置定时任务 scheduler { id: job1, func: scheduler:task, # 指向一个Python函数或方法…

ABY2.0:更低的通信开销

参考文献&#xff1a; [ABY] Demmler D, Schneider T, Zohner M. ABY-A framework for efficient mixed-protocol secure two-party computation[C]//NDSS. 2015.[ABY3] Mohassel P, Rindal P. ABY3: A mixed protocol framework for machine learning[C]//Proceedings of the…

Weblogic10中常用Linux指令

一.Weblogic 创建域 域目录/servers/AdminServer 路径下 以weblogic帐号登录&#xff08;与创建域目录相对应账户&#xff09; cd /home/weblogic/bea/weblogic92/common/bin 执行./config.sh进入配置界面。配置步骤如下&#xff1a; 1.Choose between creating and exten…

【java web】JSP-Java Server Page

前言 这个框架我用得不多&#xff0c;感觉和python的django一样&#xff0c;前后端结合太紧密了&#xff0c;适合个人开发 get 明文请求&#xff0c;可以被直接收藏 post 密文请求 JSP Java Server Page&#xff08;JSP&#xff09;HTMLJava code 步骤&#xff1a; 1.…

【数据结构初阶】二、 线性表里的顺序表

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【数据结构初阶】一. 复杂度讲解_高高的胖子的博客-CSDN博客 1 . 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实…

WMS仓储管理系统的功能与WCS系统有什么区别

在物流行业的现代化管理中&#xff0c;WMS仓储管理系统和WCS仓库控制系统是两个重要的组成部分。虽然它们都是用于仓库管理的软件系统&#xff0c;但是它们的功能和应用场景有很大的区别。本文我们将详细阐述这两者的功能和区别。 一、WMS仓储管理系统 WMS是一种软件系统&…

科技资讯|苹果Vision Pro获得被动冷却系统及数字表冠控制界面专利

据patentlyapple报道&#xff0c;美国专利商标局正式授予苹果一项与头戴式设备&#xff08;Apple Vision Pro&#xff09;相关的专利11751366&#xff0c;该设备可以提供被动冷却系统&#xff0c;利用光学组件的表面来管理热量&#xff0c;而不会对用户显示的视觉信息产生不利影…

计算机竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

[C++]杨辉三角

目录 题目 解题思路 代码实现 获取数字 打印函数 主函数 全部代码 运行结果 题目 给定一个非负整数numRows &#xff0c;生成「杨辉三角」的前numRows行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 解题思路 第k列的第i个数字的值第k-1列的(…

shell SQL 变量 Oracle shell调用SQL操作DB

注意 &#xff1a; v\\\$ 用法, “v\\\$session ” ""不能用 sqlplus -S / as sysdba << EOF set pagesize 0 set verify off set feedback off set echo off col coun new_value v_coun select count(*) coun from dual; EOF value"$?"VALUE…