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 ライブラリで正しく読み取ることができないと思われます。
このタイプのエラーの正確な原因は何ですか? PDFRendererライブラリと互換性のない新しいバージョンであるPDFがどのように生成/作成されるかが原因でしょうか?