来看一段有趣的代码

在这里插入图片描述

最近实现发票连续打印时,直接copy其他项目代码来用,主要是对文件的处理,这部分可以不涉及数据库操作,这种功能也很方便写单元测试。在写单元测试图片转PDF功能时,发现了一段有趣的代码:

protected void scaleImage(com.itextpdf.text.Image image) {float imageHeight = image.getScaledHeight();float imageWidth = image.getScaledWidth();int i = 0;while (imageHeight > 500 || imageWidth > 500) {image.scalePercent(100 - i);i++;imageHeight = image.getScaledHeight();imageWidth = image.getScaledWidth();}
}

这段代码是对图片进行缩放,如果宽和高大于500就进行缩放,有意思的地方是明明可以直接计算出缩放倍率,偏偏要从 100%(i++位置调一下也能避免一次无用功)一直尝试到符合为止,我测试的图片是宽795高528,一直尝试到62%才满足,如果图片缩放涉及IO操作,消耗的资源可能会更大,经过查看 itextpdf 源码发现 scalePercent 里面涉及几十次运算,纯计算执行几百或者几千次也很快。

这段代码的思想很好,但要谨慎使用,如果提前计算直接缩放,代码反而更简单:

protected void scaleImage(Image image) {float imageHeight = image.getScaledHeight();float imageWidth = image.getScaledWidth();float scalePercent = Math.min(500 / imageHeight, 500 / imageWidth) * 100;image.scalePercent(scalePercent);
}

做到这一步就算完事了吗?

当然不是,往PDF放图片为什么缩放呢,为什么宽高限制500呢?为什么只有一个图片的情况下,转成的PDF是一张A4纸的比例呢?为什么不像其他电子发票(不是数电发票)那样刚刚好的尺寸?

宽高限制500的情况下和其他PDF格式的发票合并到一起时明显更窄,样式不统一不好看,通过查看PDF的宽高,经过计算将宽度设置为 595 的时候样式是统一的。另外高度不应该限制500,如果发票很长,按高度缩放后会很窄,内容会看不清,因此应该只限制宽度,不限制高度。经过这种调整后代码如下:

protected void scaleImage(Image image) {float imageWidth = image.getScaledWidth();float scalePercent = 595 / imageWidth * 100;image.scalePercent(scalePercent);
}

另外就是PDF的尺寸,直接和缩放后的图片大小一致就可以,没必要浪费纸,因此改造后的整个方法如下:

protected InputStream imageToPdf(InputStream is, List<File> tempFiles) {File outFile = FileUtil.createTempFile(".pdf", true);try (FileOutputStream out = new FileOutputStream(outFile)) {Image image = Image.getInstance(IoUtil.readBytes(is));//缩放图片scaleImage(image);//设置尺寸Document document = new Document(new Rectangle(image.getScaledWidth(), image.getScaledHeight()),0, 0, 0, 0);PdfWriter.getInstance(document, out);document.open();image.setAlignment(Image.ALIGN_CENTER);document.add(image);document.close();out.flush();return Files.newInputStream(outFile.toPath());} catch (Exception e) {log.error("图片转换成pdf失败", e);throw new BusinessException("图片转换成pdf失败");} finally {IoUtil.close(is);tempFiles.add(outFile);}
}

一开始只用图片宽高设置 Document 时发现高度有截断,增加 margin 设置后变成和图片一致了。最终在合并后的PDF中,所有文档的宽度也变得整齐一致了。

在这里插入图片描述

图中上面是ofd转pdf后的页面,下面是图片转pdf后的页面。可以从图中(绿边)方框截图放大效果中看到对齐的效果,非常完美!

写代码很简单,想要写好需要多思考,还需要对自己有更高的要求。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

瑞芯微 rk3588 Linux系统备份还原 StepbyStep

1.系统备份 1.1 将瑞芯微平台嵌入式系统的root ssh 权限开通 step1:sudo vi /etc/ssh/sshd_config step2: 找到PermitRootLogin,把开关打开&#xff1a; PermitRootLogin yes step3:重启ssh服务 sudo systemctl restart sshd 1.2.使用瑞芯微的打包脚本把嵌入式系统系统打包 这…

操作系统实战(二)(linux+C语言)

实验内容 通过Linux 系统中管道通信机制&#xff0c;加深对于进程通信概念的理解&#xff0c;观察和体验并发进程间的通信和协作的效果 &#xff0c;练习利用无名管道进行进程通信的编程和调试技术。 管道pipe是进程间通信最基本的一种机制,两个进程可以通过管道一个在管道一…

代码审计平台sonarqube的安装及使用

docker搭建代码审计平台sonarqube 一、代码审计关注的质量指标二、静态分析技术分类三、使用sonarqube的目的四、sonarqube流程五、docker快速搭建sonarqube六、sonarqube scanner的安装和使用七、sonarqube对maven项目进行分析八、sonarqube分析报告解析九、代码扫描规则定制十…

激光雷达赋能盲人导航:精准安全与实施挑战并存

在当今科技的推动下&#xff0c;一款名为“蝙蝠避障”专门为盲人设计的辅助应用正逐渐成为他们独立出行的重要工具&#xff0c;特别是那些融入了激光雷达技术的应用&#xff0c;为盲人导航提供了前所未有的支持。然而&#xff0c;任何技术都有其两面性&#xff0c;接下来我们将…

Fcos源码训练编译问题

训练fcos代码时出现问题 ImportError: cannot import name ‘_C’ 原因是没有对代码进行编译 运行python setup.py develop --no-deps进行代码编译 编译过程中出现报错&#xff1a; fcos_core/csrc/cuda/ROIAlign_cuda.cu:5:10: fatal error: THC/THC.h: No such file or dire…

【Hugging Face】编写 shell 脚本在 huggingface 镜像站快速下载模型文件

前言 我们使用 Git LFS 和 wget 结合的方法&#xff0c;小文件使用 Git 下载&#xff0c;大文件使用 wget 下载 Git 下载的优缺点&#xff1a; 优点&#xff1a;相当简单 缺点&#xff1a;不支持断点续传 直接 wegt 下载比较稳定&#xff0c;但是欠缺优雅 我们可以将这两…

python + word文本框中文字识别并替换【真替换,不只是识别】

1. 简单描述 在一些转换场景下&#xff0c;文本框不会被转换&#xff0c;需要先识别成文字内容。 【识别的文字段落可能会和实际看到的效果有些差异&#xff0c;后续还需校对&#xff0c;如下图】。 不足&#xff1a;除了上面说的那个情况&#xff08;上图说的问题&#xff0…

pytest + yaml 框架 - 录制接口转 yaml 用例实现

pytest yaml 框架基本不用写 python 代码&#xff0c;只需写yaml 文件用例就能实现接口自动化。 现在引入接口录制功能&#xff0c;连 yaml 文件也不用写了&#xff0c;点点点就能生成 yaml 用例文件了。 录制功能在v1.3.4版本上实现 pip instal pytest-yaml-yoyo 环境准备 …

LLM 可以从简单数据中学习吗?

在 10 月份的一次周会结束后&#xff0c;我提到 SFT 训练后的 Loss 曲线呈现阶梯状&#xff0c;至于为什么&#xff0c;并没有人有合理的解释&#xff0c;加上当时的重心是提升次日留存率&#xff0c;Loss 曲线呈现阶梯状与次日留存率的关系还太远&#xff0c;即使有问题&#…

微信小程序按钮去除边框线

通常我们去掉按钮边框直接设置 border:0 但是在小程序中无效&#xff0c;设置outline:none也没用&#xff0c;当然可能你会说加权重无效 实际上该样式是在伪元素::after内&#xff0c;主要你检查css 还看不到有这个关系&#xff0c;鹅厂就是坑多 类样式::after {border: non…

halcon获取Licenses--每月一换

转到https://www.51halcon.com/ 点击授权&#xff0c;根据你的版本选择progress或者steady进行下载 记住每月一换哦

Ubuntu磁盘剩余空间不足,空间异常

近日发现用了3年的Ubuntu系统笔记本磁盘空间极度告急&#xff0c;上网搜了一下都是讲解如何扩容、如何重新挂载空间&#xff0c;但是博主发现/home目录明明分配了200G的空间&#xff0c;但是只剩下6G可用&#xff0c;查询所有的文件夹发现&#xff0c;所有文件加起来已使用50G左…

使用Baidu Comate五分钟 , 工作时间摸鱼8小时

Baidu Comate&#xff1a;引领智能编码新时代 文章目录 Baidu Comate&#xff1a;引领智能编码新时代一、明日工具&#xff0c;今日领先——百度Comate智能编码助手二、万变不离其宗——适配场景需求三、功能研究3.1 指挥如指掌——指令功能3.2 助手增援——插件功能使用3.3 实…

本地运行.net项目

有时候需要我们自己做一个.net的课设项目&#xff0c;但是我们有了代码后却不知道怎么运行。我们0基础来学习一下如何运行一个.net项目 1.安装visual studio 2022 不用安装老版本&#xff0c;新版就可以。安装好了2022版本&#xff0c;这是一个支持web的IDE&#xff0c;我们可…

【数据结构初阶】直接插入排序

最近浅学了直接插入排序&#xff0c;写个博客做笔记&#xff01;笔记功能除外若能对读者老爷有所帮助最好不过了&#xff01; 直接插入排序是插入排序的一种&#xff0c;那么介绍直接插入排序之前先介绍一下常见的排序算法&#xff01; 目录 1.常见的排序算法 2.直接插入排…

【LeetCode:2391. 收集垃圾的最少总时间 + 二分】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

值得收藏!!《软考信息处理技术员》必背100母题,轻松45+

距离软考考试的时间越来越近了&#xff0c;趁着这两周赶紧准备起来 今天给大家整理了——软考信息处理技术员100道经典母题&#xff0c;年年从里面抽&#xff0c;有PDF&#xff0c;可打印&#xff0c;每天刷几道。 第一章 电脑的基本操作 1、&#xff08; &#xff09;不是国产…

特产销售|基于Springboot+vue的藏区特产销售平台(源码+数据库+文档)​

目录 基于Springbootvue的藏区特产销售平台 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道…

macOS上将ffmpeg.c编译成Framework

1 前言 本文介绍下在macOS上将ffmpeg的fftools目录下的ffmpeg.c程序&#xff0c;也就是ffmpeg的命令行程序&#xff0c;编译成framework的方法。编译成.a或.dylib亦是类似。 编译环境如下&#xff1a; xcode15.3&#xff1b;ffmpeg branch release/6.1; 2 编译ffmpeg 首先clon…

智能AI个人名片小程序源码系统 带完整的安装代码包以及搭建部署教程

在当今数字化时代&#xff0c;个人名片不再仅仅是一张简单的纸质卡片&#xff0c;而是演变成了一种更加智能、便捷的数字化工具。为了满足这一需求&#xff0c;小编给大家分享一款智能AI个人名片小程序源码系统&#xff0c;该系统不仅提供了完整的安装代码包&#xff0c;还附带…