我正在使用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都是专有的,不能共享)。
尝试使用PDFFile.getPage(1)
引用PDF的第一页时,我收到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库不兼容的较新版本?