如何在 Java 中将常见文档转换为 PNG 图像数组

        如何使用 Java 中的 Web API 轻松地将各种常见文档格式转换为 PNG 图像数组。在进入本文的演示部分之前,我们将首先回顾一下将文档转换为不太灵活的格式背后的常见逻辑,并最终讨论 PNG 格式相对于其他常见格式(如 PDF 或 JPG)提供的优势。

24d7ca1625e5fa084ad37fdb321b2b1b.png

为什么要将文档转换为不灵活的格式?

        针对文档编辑和操作优化的文件格式通常不会针对其他方案的效率进行优化。有一长串论据支持将此类文档转换为静态格式(如 PDF),用于文档编辑和操作以外的任何场景。

        内容安全是其中最有力的论据之一。设计为在编辑应用程序中打开和操作的文档格式在设计上保留了高度可访问和易于互换的属性,这意味着未经请求的第三方(即未知的陌生人)可以随意更改这些应用程序中的文档。其中技术娴熟的人甚至可以毫不费力地对常见的文档格式进行编程/自动更改。例如,不乏旨在解压缩和操作 XLSX、DOCX 或 PPTX 等开放式办公室 XML (OpenXML) 文件的 API 和库(我在之前的文章中已经写过很多)。以原始格式公开共享或显示 Office 文档会带来麻烦;在现实世界中,我们几乎看不到这样做是有原因的。

        当然,这不仅仅是关于安全性。复杂的 OpenXML 文件和其他类似的分层文档格式旨在将大量数据保留在一个地方(包括文本、链接、元数据和多媒体),这使得存储、传输或流式传输这些文件成为任何规模的负担。例如,如果我们要与网络中的利益相关者共享一系列最终确定的 Excel XLSX 报告(包括图形和数字),我们将在此过程中占用大量带宽,因此我们的传输速度会受到影响。如果我们将所有这些文件存储在一起而不压缩它们,我们将消耗不成比例的大量文件存储分配,随着时间的推移,这可能会证明成本很高——尤其是对于现代即用即付的云存储模型。同样,如果我们编写应用程序以将 Excel 文件管道传输到 Web 应用程序门户上基于 Web 的文件查看器(即,使用 iframe 标记),我们可能会大大减慢该页面的加载速度。

在现实世界中,这些挑战的结果是,大多数文档在进入存储、传输或流式处理状态之前,通常会转换为安全、静态且相对简单的格式。在大多数情况下,该格式为 PDF。

PDF的优缺点

        PDF 是大多数常见内容形式(尤其是 OpenXML 文档)事实上的发布格式,这是有充分理由的。它可以在任何 Web 浏览器上访问,并提供各种安全优势,同时与无数文件渲染和处理应用程序保持兼容。它可以结构为多媒体矢量文件或光栅(位图)文件,确保可以适应各种独特的内容类型,以适应同样广泛的显示方案。

        但是,PDF本身并不能立即解决的问题是压缩。PDF 仍然是相对复杂的文件,通常在其文件结构中存储布局、字体、矢量图形、文档历史记录和文档元数据。此外,光栅 PDF 以位图格式显示像素,默认情况下,该格式包含比其他图像类型更高的颜色深度范围(例如 24 位或 32 位)。这使得光栅 PDF 成为高质量静态文档内容显示和文档打印的绝佳选择,但对于轻量级存储和传输来说却不太有利。

选择PNG而不是JPG作为PDF替代品

        当 PDF 文件结构的特性和功能超出我们的需求时,我们可以将注意力转向更简单、重量更轻的格式选项。在这些选项中,有两种最常见的图像格式:PNG 和 JPG。

        这两种格式都提供了显着的压缩功能,JPG 比 PNG 在更大程度上做到了这一点。然而,对于JPG,这种压缩的成本要高得多。JPG 压缩算法试图通过删除一些我们通常不容易注意到的图像细节来减小文件大小,使用颜色子采样(即以低于亮度信息的分辨率存储颜色信息)和量化(即降低图像中颜色和亮度值的整体精度)等技术。随着时间的推移,JPG压缩变得越来越明显,这使得将详细文档转换为JPG屏幕截图成为一项冒险的工作。另一方面,PNG 牺牲了稍大的最终文件大小,以获得不会丢弃与图像质量相关的数据的压缩算法。PNG 压缩采用预测编码和像素值过滤等概念来优化图像数据,并使用 Deflate Compression 来识别图像数据中的重复模式,并用较短的代码替换这些模式。生成的 PNG 文件可能比 JPG 略大,但它们的质量可以保证随着时间的推移保持一致,使其成为存储和显示高质量文档内容的绝佳选择。

示范

        在本文的演示部分,我们将逐步学习如何调用免费 API,该 API 可自动检测各种输入文档类型(包括所有主要的 Office 文档格式、PDF 和 100 多种不同的图像格式)并将其转换为 PNG 图像数组。在实践中,它实际上是一种自动屏幕截图解决方案,我们可以直接将其插入到我们的 Java Web 应用程序中。它通过将 PNG 文件内容作为临时 URL 数组(每个 PNG 图像一个)返回来优化转换后的下载过程,随后可以下载这些 URL 并将其转换为文件字节。要使用此 API,我们只需要一个免费的 API 密钥,这将使我们每月使用 800 次 API 调用的限制。

要开始构建我们的 API 调用,我们将首先安装 Maven SDK(jitpack 用于动态编译库)。让我们在 pom.xml 中添加对存储库的引用。

XML格式

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

之后,让我们在 pom.xml 中添加对依赖项的引用:

XML格式

<dependencies>
<dependency>
    <groupId>com.github.Cloudmersive</groupId>
    <artifactId>Cloudmersive.APIClient.Java</artifactId>
    <version>v4.25</version>
</dependency>
</dependencies>

在下一步中,我们会将以下导入添加到文件顶部:

// Import classes:
//import com.cloudmersive.client.invoker.ApiClient;
//import com.cloudmersive.client.invoker.ApiException;
//import com.cloudmersive.client.invoker.Configuration;
//import com.cloudmersive.client.invoker.auth.*;
//import com.cloudmersive.client.ConvertDocumentApi;

之后,我们将添加配置代码段来捕获我们的 API 密钥:

ApiClient defaultClient = Configuration.getDefaultApiClient();

// Configure API key authorization: Apikey
ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
Apikey.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//Apikey.setApiKeyPrefix("Token");

最后,我们将添加以下代码片段以创建 API 实例并调用该函数进行转换:

ConvertDocumentApi apiInstance = new ConvertDocumentApi();
File inputFile = new File("/path/to/inputfile"); // File | Input file to perform the operation on.
try {
    AutodetectToPngResult result = apiInstance.convertDocumentAutodetectToPngArray(inputFile);
    System.out.println(result);
} catch (ApiException e) {
    System.err.println("Exception when calling ConvertDocumentApi#convertDocumentAutodetectToPngArray");
    e.printStackTrace();
}

我们可以通过几种不同的方式处理从临时 URL 到 PNG 文件字节的转换。我们可以使用以下代码进行辅助 API 调用(来自同一库并遵循与以前相同的基本结构)来处理该问题:

// Import classes:
//import com.cloudmersive.client.invoker.ApiClient;
//import com.cloudmersive.client.invoker.ApiException;
//import com.cloudmersive.client.invoker.Configuration;
//import com.cloudmersive.client.invoker.auth.*;
//import com.cloudmersive.client.EditDocumentApi;

ApiClient defaultClient = Configuration.getDefaultApiClient();

// Configure API key authorization: Apikey
ApiKeyAuth Apikey = (ApiKeyAuth) defaultClient.getAuthentication("Apikey");
Apikey.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//Apikey.setApiKeyPrefix("Token");

EditDocumentApi apiInstance = new EditDocumentApi();
FinishEditingRequest reqConfig = new FinishEditingRequest(); // FinishEditingRequest | Cloudmersive Document URL to complete editing on
try {
    byte[] result = apiInstance.editDocumentFinishEditing(reqConfig);
    System.out.println(result);
} catch (ApiException e) {
    System.err.println("Exception when calling EditDocumentApi#editDocumentFinishEditing");
    e.printStackTrace();
}

或者,我们可以使用 from 类( 的基本部分)。这允许我们从文件 URL 创建一个 URL 对象,从 URL 读取和写入文件字节,并将字节流转换为可下载的文件内容。java.net.HttpURLConnectionjava.netJDK

        无论哪种情况,我们只需要将文件字节写入新的 PNG 文档,我们就可以轻松地在转换工作流程下游的任何位置存储、传输或流式传输该内容。

以静态图像格式存储、传输和流式传输文档的一些原因,并了解了 PNG 如何以 PDF 和 JPG 无法做到的方式提供轻量级无损压缩。

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨曦_子画

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值