Java 使用html2image将html生成缩略图图片

POM文件添加Maven依赖

		<dependency><groupId>gui.ava</groupId><artifactId>html2image</artifactId><version>0.9</version></dependency>

主要代码:

        String coverPath = null;try {HtmlImageGenerator imageGenerator = new HtmlImageGenerator();imageGenerator.loadHtml(lzDocs.getContent());//也可以根据html url引用 loadUrl的方式加载Thread.sleep(1000); //有时会有加载图片延迟,因此这里设置下延时BufferedImage cover = imageGenerator.getBufferedImage();//获取图片cover = ImageUtils.getCoverImage(cover);//将图片转成综略图String coverName = UUIDGenerator.generate().toString() + ".png";MultipartFile mpFile = FileUtils.imageToMpFile(cover, coverName);coverPath = sysBaseAPI.upload(mpFile,"cover", uploadType);//上传文件到服务器} catch (Exception e) {e.printStackTrace();}

图片工具类,供主要代码调用

public class ImageUtils {/*** bufferedImage转InputStream*/public static InputStream bufferedImageToInputStream(BufferedImage image) {ByteArrayOutputStream os = new ByteArrayOutputStream();try {ImageIO.write(image, "png", os);InputStream input = new ByteArrayInputStream(os.toByteArray());return input;} catch (IOException e) {}return null;}/*** 获取图片大小信息*/public static Rectangle getImgRect(BufferedImage image) throws IOException {Iterator readers = ImageIO.getImageReadersByFormatName("png");ImageReader reader = (ImageReader) readers.next();InputStream source = bufferedImageToInputStream(image);ImageInputStream iis = ImageIO.createImageInputStream(source);reader.setInput(iis, true);int imageIndex = 0;return new Rectangle(0, 0, reader.getWidth(imageIndex), reader.getHeight(imageIndex));}/*** 图片裁剪,按指定大小裁剪*/public static BufferedImage imageCut(BufferedImage image, Rectangle rect) throws IOException {// 取得图片读入器Iterator readers = ImageIO.getImageReadersByFormatName("png");System.out.println(readers);ImageReader reader = (ImageReader) readers.next();System.out.println(reader);// 取得图片读入流InputStream source = bufferedImageToInputStream(image);ImageInputStream iis = ImageIO.createImageInputStream(source);reader.setInput(iis, true);// 图片参数ImageReadParam param = reader.getDefaultReadParam();int imageIndex = 0;//Rectangle rect = new Rectangle(0, 0, reader.getWidth(imageIndex), 100);param.setSourceRegion(rect);BufferedImage bi = reader.read(0, param);iis.close();source.close();return bi;}/*** 压缩图片,用于高质量图片质量降低,改变图片大小*/public static BufferedImage compressImage(BufferedImage imageByte, int ppi) {BufferedImage smallImage = null;int width = 0, height = 0;if (imageByte == null)return null;InputStream byteInput = bufferedImageToInputStream(imageByte);try {Image image = ImageIO.read(byteInput);int w = image.getWidth(null);int h = image.getHeight(null);// adjust weight and height to avoid image distortiondouble scale = 0;scale = Math.min((float) ppi / w, (float) ppi / h);width = (int) (w * scale);width -= width % 4;height = (int) (h * scale);if (scale >= (double) 1)return imageByte;BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);buffImg.getGraphics().drawImage(image.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);//ByteArrayOutputStream out = new ByteArrayOutputStream();//ImageIO.write(buffImg, "png", out);smallImage = buffImg;} catch (IOException e) {e.printStackTrace();}return smallImage;}/*** 将BufferedImage转换为byte[]* @param image* @return*/public static byte[] bufferedImageToByteArray(BufferedImage image) throws IOException{ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(image, "png", os);return os.toByteArray();}/*** 将BufferedImage转换pdf*/public static String imageToPdf(List<BufferedImage> images) throws IOException {log.info("图片转pdf开始===============");String newFile = StrUtil.uuid().replace("-", "") + ".pdf";PdfWriter pdfWriter = new PdfWriter( newFile);PdfDocument pdfDocument = new PdfDocument(pdfWriter);Document document = new Document(pdfDocument);for (BufferedImage image : images) {byte[] data = bufferedImageToByteArray(image);com.itextpdf.layout.element.Image img = new com.itextpdf.layout.element.Image(ImageDataFactory.createPng(data));document.add(img);}document.close();log.info("图片转pdf结束===============");return newFile;}/*** 获取缩略图图片,用作封面,按长宽比例设备,高度太高裁掉,高度太低补余白*/public static BufferedImage getCoverImage (BufferedImage originalImage) throws IOException {BufferedImage result = null;// 获取图片的长宽int originalWidth = originalImage.getWidth();int originalHeight = originalImage.getHeight();Rectangle rect = ImageUtils.getImgRect(originalImage);if (rect.getHeight() > rect.getWidth()) {rect.setRect(0,0, rect.getWidth(), rect.getWidth() / 1.3);result = ImageUtils.imageCut(originalImage, rect);} else {int newWidth = 800;int newHeight = 600;// 计算缩放比例double scale = Math.min((double) newWidth / originalWidth, (double) newHeight / originalHeight);// 计算调整后的长宽int scaledWidth = (int) (originalWidth * scale);int scaledHeight = (int) (originalHeight * scale);// 创建新的BufferedImage对象,添加余白BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);Graphics2D g = resizedImage.createGraphics();Color fillColor = new Color(255, 255, 255); // 白颜色g.setColor(fillColor);g.fillRect(0, 0, newWidth, newHeight);g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);g.dispose();result = resizedImage;}return result;}}

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

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

相关文章

C++-模板

目录 一.泛型编程 二.模板的分类 三.函数模板 1.函数模板的概念 2.函数模板格式 3.函数模板的原理 4.函数模板的实例化 a.隐式实例化 b.显式实例化 5.模板参数的匹配原则 四.类模板 1.类模板的定义格式 2.类模板的实例化 五.class和typename的区别 六.非类型模板…

docker配置redis插件

docker配置redis插件 运行容器redis_6390 docker run -it \ --name redis_6390 \ --privileged \ -p 6390:6379 \ --network wn_docker_net \ --ip 172.18.12.19 \ --sysctl net.core.somaxconn1024 \ -e TIME_ZONE"Asia/Shanghai" -e TZ"Asia/Shanghai"…

【大连民族大学C语言CG题库练习题】——加密文件1

【问题描述】有一种加密方法为&#xff1a;其使用一个字母串&#xff08;可以含重复字母&#xff0c;字母个数不超过50&#xff09;作为密钥。假定密钥单词串为feather&#xff0c;则先去掉密钥单词中的重复字母得到单词串feathr&#xff0c;然后再将字母表中的其它字母以反序追…

Nacos源码解读04——服务发现

Nacos服务发现的方式 1.客户端获取 1.1:先是故障转移机制判断是否去本地文件中读取信息&#xff0c;读到则返回 1.2:再去本地服务列表读取信息(本地缓存)&#xff0c;没读到则创建一个空的服务&#xff0c;然后立刻去nacos中读取更新 1.3:读到了就返回&#xff0c;同时开启定时…

nginx优雅如何优雅的接管【跨域配置】

跨域问题太常见了&#xff0c;这里不做详细赘述。文章主要想说一下&#xff0c;如何统一管理和更好的来管理 跨域配置 跨域的常见配置有两种 后台代码设置和网关设置 1、后台代码设置 以springboot为例代码如下&#xff08;水一下文章长度...&#xff09; Configuration pu…

洛谷 P2935 [USACO09JAN] Best Spot S

文章目录 [USACO09JAN] 最佳牧场 S题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 思路解析CODE [USACO09JAN] 最佳牧场 S 题目链接&#xff1a;https://www.luogu.com.cn/problem/P2935 题目描述 贝茜&#xff0c;总是希望优化她的生活&#xff0c;她发现自己…

Linux下activemq的安装与安装成功确认

一、下载 apache-activemq-5.14.0-bin.tar.gz 二、安装 将压缩包拷入linux内&#xff0c;进行解压tar -zxvf apache-activemq-5.14.0-bin.tar.gz&#xff0c;与redis、nginx不同的是&#xff0c;active解压不需要安装就可以直接启动&#xff01; 启动命令&#xff1a;./bin…

1949-2021年全国31省公路里程数据

1949-2021年全国31省公路里程数据 1、指标&#xff1a;公路里程 2、范围&#xff1a;包括31省 1978-2021年期间无缺失 3、来源&#xff1a;各省NJ、产业NJ、各省统计GB 4、指标解释&#xff1a;公路里程指报告期末公路的实际长度。 统计范围&#xff1a;包括城间、城乡间、乡…

Rocketmq架构

NameServer&#xff1a;作为注册中心&#xff0c;提供路由注册、路由踢出、路由发现功能&#xff0c;舍弃强一致&#xff0c;保证高可用&#xff0c;集群中各个节点不会实时通讯&#xff0c;其中一个节点下线之后&#xff0c;会提供另外一个节点保证路由功能。 Rocket mq name…

java学习part32StringBuffer和StringBuilder

Java中的值传递和引用传递&#xff08;详解&#xff09; - 知乎 (zhihu.com) 146-常用类与基础API-StringBuffer与StringBuilder的源码分析、常用方法_哔哩哔哩_bilibili 1. 2.扩容机制 不够用&#xff1a;长度为 原长度*22&#xff1b;如果还不够&#xff0c;那么就扩容到目…

软件工程期末复习(2)

学习资料 设计模式与软件体系结构【期末全整理答案】_软件设计模式与体系结构期末考试题_鸽子不二的博客-CSDN博客 软件设计与体系结构(第二版)部分习题_软件设计与体系结构第二版课后答案-CSDN博客 软件体系结构试题库试题和答案 - 豆丁网Docin 软件设计与体系结构复习 - CN…

当springsecurity出现SerializationException问题

当springsecurity出现SerializationException问题 01 异常发生场景 当我使用springsecurity时&#xff0c;登录成功后携带token访问接口出了问题 org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized field "userna…

多文件夹图片预处理:清除空值、重置大小、分割训练集

→ 清理空值 防止出现cannot identify image file 参考Python数据清洗----删除读取失败图片__简单版_python用pil读取图片出错删除掉-CSDN博客 #%pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python #可能需要重启jupyter import os import shutil imp…

【Unity动画】状态机添加参数控制动画切换(Animator Controller)

Unity - 手册&#xff1a;动画参数 在Unity中&#xff0c;动画状态的切换是通过Animator Controller中的过渡&#xff08;Transition&#xff09;来实现的。过渡是状态之间的连接&#xff0c;控制过渡一般都是靠调用代码参数 我们来实现一个案例&#xff1a; 创建动画状态机&a…

构造函数的定义

当定义一个构造函数时&#xff0c;它的格式如下&#xff1a; ClassName(parameters) : member1(initializer), member2(initializer), ... {// 构造函数的主体 }其中&#xff1a; ClassName 是结构体或类的名称&#xff0c;表示构造函数所属的结构体或类。parameters 是构造函…

leetcode 142.环形链表2

我来更新 leetcode 题目了&#xff0c;接着上一次&#xff0c;这一次是上一道题目的提升&#xff08;有点数学题的感觉&#xff09; 142.环形链表2 题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表…

识KDJ指标,看懂超买超卖信号

一、认识KDJ 1、KDJ的含义 KDJ分析股票中短期趋势的一个常用指标&#xff0c;中文名称“随机指标”。它是一个综合考虑股票最高价、最低价和收盘价的技术指标&#xff0c;能够帮助我们根据历史价格预测出股票未来的价格走势。在实际应用的过程中&#xff0c;它的短期预测功能要…

JAVA毕业设计113—基于Java+Springboot+Vue的体育馆预约系统(源代码+数据库+12000字论文)

基于JavaSpringbootVue的体育馆预约系统(源代码数据库12000字论文)113 一、系统介绍 本项目前后端分离&#xff0c;本系统分为管理员、用户两种角色 用户角色包含以下功能&#xff1a; 注册、登录、场地(查看/预订/收藏/退订)、在线论坛、公告查看、我的预订管理、我的收藏…

TimeGPT:时间序列预测模型实例

时间序列预测领域正在经历一个非常激动人心的时期。在过去的三年里&#xff0c;我们见证了许多重要的贡献&#xff0c;如N-BEATS、N-HiTS、PatchTST和TimesNet等。同时&#xff0c;大型语言模型&#xff08;LLM&#xff09;近来在流行度方面取得了很大的成功&#xff0c;例如Ch…

PMP-01

考纲 需要看的书籍 学习计划