计算机系统应用教程网站

网站首页 > 技术文章 正文

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

btikc 2024-10-23 09:10:16 技术文章 7 ℃ 0 评论


了解如何将 Office 文档、PDF 和 100 多个图像转换为一组 PNG 图像,并了解进行 PNG 转换相对于其他格式的一些优势

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

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

针对文档编辑和操作进行优化的文件格式通常不会针对其他情况下的效率进行优化。对于除文档编辑和操作之外的任何场景,有很多论据支持将此类文档转换为静态格式(如 PDF)。

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

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


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

PDF 的优点和缺点

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

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


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

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

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

示例

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

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

<repositories>

<repository>

<id>jitpack.io</id>

<url>https://jitpack.io</url>

</repository>

</repositories>


之后,让我们在 pom.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();

}

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

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

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表