我正在使用PDFRenderer 0.9.1 版在 ColdFusion 中以编程方式将 PDF 转换为 PNG。
这是我为此编写的 UDF:
<cffunction
name="pdfToImageFile"
returntype="String"
output="false"
hint="Converts a phsyical PDF File to a physical Image file and returns the absolute path of the new Image file">
<cfargument name="sourcePath" type="String" default="" />
<cfargument name="destinationPath" type="String" default="" />
<cfargument name="format" type="String" default="png" />
<cfset var LOCAL = {} />
<cfif NOT isValidPDF(Trim(ARGUMENTS.sourcePath))>
<cfthrow
message="Source file not specified or not a valid PDF file." />
</cfif>
<cfif NOT DirectoryExists(Trim(ARGUMENTS.destinationPath))>
<cfthrow message="Inavlid Destination path." />
</cfif>
<cfif
NOT ListFindNoCase(
GetWriteableImageFormats(),
Trim(ARGUMENTS.format)
)>
<cfthrow message="Inavlid Image format specified." />
</cfif>
<cfscript>
LOCAL.DestinationFilePath =
Trim(ARGUMENTS.destinationPath)
& "\"
& REQUEST.UDFLib.File.getFileNameWithoutExtension(
GetFileFromPath(ARGUMENTS.sourcePath)
)
& "."
& LCase(Trim(ARGUMENTS.format));
LOCAL.RandomAccessFile =
CreateObject(
"java",
"java.io.RandomAccessFile"
).init(
CreateObject(
"java",
"java.io.File"
).init(ARGUMENTS.sourcePath),
"r"
);
LOCAL.FileChannel = LOCAL.RandomAccessFile.getChannel();
LOCAL.PDFFile =
CreateObject(
"java",
"com.sun.pdfview.PDFFile"
).init(
LOCAL.FileChannel.map(
CreateObject(
"java",
"java.nio.channels.FileChannel$MapMode"
).READ_ONLY,
0,
LOCAL.FileChannel.size()
)
) />
LOCAL.PDFPage = LOCAL.PDFFile.getPage(1) />
// The following line throws an exception "Element PDFPAGE is undefined in LOCAL."
LOCAL.Rectangle = LOCAL.PDFPage.getBBox();
LOCAL.BufferedImage =
CreateObject(
"java",
"java.awt.image.BufferedImage"
).init(
LOCAL.Rectangle.width,
LOCAL.Rectangle.height,
CreateObject(
"java",
"java.awt.image.BufferedImage"
).TYPE_INT_RGB
);
LOCAL.Graphics = LOCAL.BufferedImage.createGraphics();
LOCAL.Graphics.drawImage(
LOCAL.PDFPage.getImage(
LOCAL.Rectangle.width,
LOCAL.Rectangle.height,
LOCAL.Rectangle,
JavaCast("null", ""),
true,
true
),
0,
0,
JavaCast("null", "")
);
LOCAL.Graphics.dispose();
LOCAL.ImageFile =
CreateObject(
"java",
"java.io.File"
).init(LOCAL.DestinationFilePath);
// Delete existing image file
if (LOCAL.ImageFile.exists())
LOCAL.ImageFile.delete();
// Export the image to the specified format
CreateObject(
"java",
"javax.imageio.ImageIO"
).write(
LOCAL.BufferedImage,
JavaCast("string", Trim(ARGUMENTS.format)),
LOCAL.ImageFile
);
LOCAL.RandomAccessFile.close();
return LOCAL.DestinationFilePath;
</cfscript>
</cffunction>
这适用于我扔给它的大多数 PDF。但是,它偶尔会为某些 PDF 引发异常(所有 PDF 都是专有的,不能共享)。
尝试使用 引用 PDF 的第一页时PDFFile.getPage(1)
,我收到 ColdFusion 异常:Element PDFPAGE is undefined in LOCAL.
.
我已经通过调试器运行了这个,经过更深入的检查,我看到了某个 PDF 的以下值:
PDFFile.getNumPages() : 0
PDFFile.getVersionString() : 1.7
PDFFile.getRoot() :
Indirect to #182
Catalog dictionary. Keys:
StructTreeRoot Indirect to #40com.sun.pdfview.PDFParseException: Could not decrypt: Need at least 2880 bytes of space in output buffer
Pages Indirect to #178com.sun.pdfview.PDFParseException: Could not decrypt: Need at least 80 bytes of space in output buffer
Type Name: /Catalog
ViewerPreferences Untyped dictionary. Keys:
Direction Name: /L2R
Metadata Indirect to #23
Caught an error: com.sun.pdfview.PDFParseException: Could not decrypt: Need at least 2672 bytes of space in output buffer
MarkInfo Untyped dictionary. Keys:
Marked Boolean: true
我不精通 Java,所以我不知道这一切意味着什么,但这让我相信 PDF 格式不正确,Java 库无法正确读取。
知道究竟是什么可能导致这种类型的错误吗?可能是因为 PDF 的生成/制作方式是与 PDFRenderer 库不兼容的较新版本吗?