印刷に適したレイアウトのPDFを作成できます。
フォームフィールドをフラット化したり、ページサイズやページの向きを設定したり、複数のページを1ページに配置したりできます。
ご注意ください:
このAdd-onに印刷機能はありません。
印刷機能はPDF Printer APIで利用できます。
Toolbox Add-onのAPIリファレンスはこちらです。(すべて英文)
C#のサンプルプロジェクトではPdftools SDK(Toolbox Add-on)ライブラリ(DLL)をNuGetから自動でダウンロードします。
CのサンプルプロジェクトにはPdftools SDK(Toolbox Add-on)ライブラリ(DLL)が含まれています。
License Agreement(利用許諾契約書)が含まれていますので必ず確認してください。
このプロジェクトでは、フォームフィールドをその視覚的な外観を維持しながら非インタラクティブなコンテンツに変換します。
フォーム フィールドの外観をフラット化し、すべてのインタラクティブな要素を破棄します。
// 入力PDFを開く
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
szInPath, szErrorBuff, Ptx_GetLastError());
// 出力PDFを生成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
szOutPath, szErrorBuff, Ptx_GetLastError());
// ドキュメント全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// コピーオプションの設定: フォームフィールドのフラット化を有効にする
pCopyOptions = PtxPdf_PageCopyOptions_New();
PtxPdf_PageCopyOptions_SetFormFields(pCopyOptions, ePtxPdfForms_FormFieldCopyStrategy_Flatten);
// 全てのページをコピー
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// コピーしたページを出力ファイルに追加
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
_T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages),
_T("Failed to add copied pages to output. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// ビュワー設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
// 入力PDFを開く
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// 出力PDFを生成
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// ドキュメント全体のデータをコピー
CopyDocumentData(inDoc, outDoc);
// フォームフィールドのフラット化を含むコピーオプションを定義
PageCopyOptions copyOptions = new PageCopyOptions();
copyOptions.FormFields = FormFieldCopyStrategy.Flatten;
// すべてのページをコピーして、出力ドキュメントに追加
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// ドキュメント全体のデータをコピー
// 出力色特性設定
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// メタデータ
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// ビュワー設定
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// プレーンな埋め込みファイル
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
def copy_document_data(in_doc: Document, out_doc: Document):
# ドキュメント全体のデータをコピー
# 出力色特性設定
if in_doc.output_intent is not None:
in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
# メタデータ
out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
# ビュワー設定
out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
# 関連ファイル(PDF/A-3およびPDF 2.0のみ)
outAssociatedFiles = out_doc.associated_files
for in_file_ref in in_doc.associated_files:
outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
# プレーンな埋め込みファイル
out_embedded_files = out_doc.plain_embedded_files
for in_file_ref in in_doc.plain_embedded_files:
out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
# 入力PDFを開く
with io.FileIO(input_file_path, "rb") as in_stream:
with Document.open(in_stream, None) as in_doc:
# 出力PDFを生成
with io.FileIO(output_file_path, "wb+") as out_stream:
with Document.create(out_stream, in_doc.conformance, None) as out_doc:
# ドキュメント全体のデータをコピー
copy_document_data(in_doc, out_doc)
# フォームフィールドのフラット化オプションを設定
copy_options = PageCopyOptions()
copy_options.form_fields = FormFieldCopyStrategy.FLATTEN
# フラット化オプションを使用してすべてのページをコピー
copied_pages = PageList.copy(out_doc, in_doc.pages, copy_options)
out_doc.pages.extend(copied_pages)
このプロジェクトでは、ページの向きを検出し、目的のページ形式に適合しない場合は自動的に回転および拡大縮小します。
PDFの各ページを指定されたのページ形式に適合させます。
// 入力PDFを開く
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
szInPath, szErrorBuff, Ptx_GetLastError());
// 出力PDFを生成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
szOutPath, szErrorBuff, Ptx_GetLastError());
// ドキュメント全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// ページのコピーオプションを設定
pCopyOptions = PtxPdf_PageCopyOptions_New();
// 全てのページをコピー
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
_T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
for (int iPage = 0; iPage < PtxPdf_PageList_GetCount(pInPageList); iPage++)
{
TPtxGeomReal_Size pageSize;
TPtxGeomReal_Size rotatedSize;
BOOL bRotate;
pInPage = PtxPdf_PageList_Get(pInPageList, iPage);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPage = NULL;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pInPage, &pageSize), _T("%s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
bRotate = bAllowRotate && (pageSize.dHeight >= pageSize.dWidth) != (targetSize.dHeight >= targetSize.dWidth);
if (bRotate)
{
rotatedSize.dWidth = pageSize.dHeight;
rotatedSize.dHeight = pageSize.dHeight;
}
else
{
rotatedSize = pageSize;
}
if (rotatedSize.dWidth == targetSize.dWidth && rotatedSize.dHeight == targetSize.dWidth)
{
// サイズが正しい場合に、ページのみをコピー
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage,
_T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
if (bRotate)
{
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_Rotate(pOutPage, ePtxGeom_Rotation_Clockwise),
_T("Failed to rotate page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
}
}
else
{
TPtxPdfContent_Group* pGroup = NULL;
TPtxPdfContent_Content* pContent = NULL;
TPtxGeomReal_AffineTransform transform;
TPtxGeomReal_Point position;
TPtxGeomReal_Point point;
// 正しいサイズの新しいページを作成し、既存のページをその上に収める
pOutPage = PtxPdf_Page_Create(pOutDoc, &targetSize);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to create a new page. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// ページをグループとしてコピー
pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// グループのスケーリングと位置を計算
double scale = MIN(targetSize.dWidth / rotatedSize.dWidth, targetSize.dHeight / rotatedSize.dHeight);
// 位置を計算
position.dX = (targetSize.dWidth - pageSize.dWidth * scale) / 2;
position.dY = (targetSize.dHeight - pageSize.dHeight * scale) / 2;
pContent = PtxPdf_Page_GetContent(pOutPage);
// コンテンツジェネレータを作成
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator,
_T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
// 変換を計算して適用
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_GetIdentity(&transform),
_T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
PtxGeomReal_AffineTransform_Translate(&transform, position.dX, position.dY),
_T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Scale(&transform, scale, scale),
_T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
point.dX = pageSize.dWidth / 2.0;
point.dY = pageSize.dHeight / 2.0;
// 入力ファイルを回転
if (bRotate)
{
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Rotate(&transform, 90, &point),
_T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
}
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_Transform(pGenerator, &transform),
_T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Formを描画
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, NULL, NULL),
_T("Failed to paint the group. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
PtxPdfContent_ContentGenerator_Close(pGenerator);
pGenerator = NULL;
if (pGenerator != NULL)
Ptx_Release(pGenerator);
if (pGroup != NULL)
Ptx_Release(pGroup);
}
// 出力ドキュメントにページを追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
_T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
if (pOutPage != NULL)
{
Ptx_Release(pOutPage);
pOutPage = NULL;
}
if (pInPage != NULL)
{
Ptx_Release(pInPage);
pInPage = NULL;
}
}
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// ビュワー設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
// 入力PDFを開く
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// 出力PDFを生成
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// ドキュメント全体のデータをコピー
CopyDocumentData(inDoc, outDoc);
// ページのコピーオプションを 定義
PageCopyOptions copyOptions = new PageCopyOptions();
// ページをコピー
foreach (Page inPage in inDoc.Pages)
{
Page outPage = null;
Size pageSize = inPage.Size;
bool rotate = AllowRotate &&
(pageSize.Height >= pageSize.Width) != (TargetSize.Height >= TargetSize.Width);
Size rotatedSize = pageSize;
if (rotate)
rotatedSize = new Size { Width = pageSize.Height, Height = pageSize.Width };
if (rotatedSize.Width == TargetSize.Width && rotatedSize.Height == TargetSize.Width)
{
// サイズが正しい場合に、ページのみをコピー
outPage = Page.Copy(outDoc, inPage, copyOptions);
if (rotate)
outPage.Rotate(Rotation.Clockwise);
}
else
{
// 正しいサイズの新しいページを作成し、既存のページをその上に収める
outPage = Page.Create(outDoc, TargetSize);
// ページをグループとしてコピー
Group group = Group.CopyFromPage(outDoc, inPage, copyOptions);
// グループのスケーリングと位置を計算
double scale = Math.Min(TargetSize.Width / rotatedSize.Width,
TargetSize.Height / rotatedSize.Height);
// 位置を計算
Point position = new Point
{
X = (TargetSize.Width - pageSize.Width * scale) / 2,
Y = (TargetSize.Height - pageSize.Height * scale) / 2
};
// コンテンツジェネレータを作成
using ContentGenerator generator = new ContentGenerator(outPage.Content, false);
// 変換を計算して適用
AffineTransform transform = AffineTransform.Identity;
transform.Translate(position.X, position.Y);
transform.Scale(scale, scale);
Point point = new Point()
{
X = pageSize.Width / 2.0,
Y = pageSize.Height / 2.0
};
// 入力ファイルを回転
if (rotate)
transform.Rotate(90, point);
generator.Transform(transform);
// グループを描画
generator.PaintGroup(group, null, null);
}
// 出力ドキュメントにページを追加
outDoc.Pages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// ドキュメント全体のデータをコピー
// 出力色特性設定
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// メタデータ
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// ビュワー設定
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// プレーンな埋め込みファイル
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
def copy_document_data(in_doc: Document, out_doc: Document):
# ドキュメント全体のデータをコピー
# 出力色特性設定
if in_doc.output_intent is not None:
in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
# メタデータ
out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
# ビュワー設定
out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
# 関連ファイル(PDF/A-3およびPDF 2.0のみ)
outAssociatedFiles = out_doc.associated_files
for in_file_ref in in_doc.associated_files:
outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
# プレーンな埋め込みファイル
out_embedded_files = out_doc.plain_embedded_files
for in_file_ref in in_doc.plain_embedded_files:
out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
def scale_pages_to_fit(in_doc: Document, out_doc: Document):
copy_options = PageCopyOptions()
# ページをコピー
for in_page in in_doc.pages:
page_size = in_page.size
rotate = (
ALLOW_ROTATE
and (page_size.height >= page_size.width) != (TARGET_SIZE.height >= TARGET_SIZE.width)
)
rotated_size = Size(
width=page_size.height, height=page_size.width
) if rotate else page_size
if rotated_size.width == TARGET_SIZE.width and rotated_size.height == TARGET_SIZE.height:
# サイズが正しい場合に、ページのみをコピー
out_page = Page.copy(out_doc, in_page, copy_options)
if rotate:
out_page.rotate(90) # Clockwise rotation
else:
# 正しいサイズの新しいページを作成し、既存のページをその上に収める
out_page = Page.create(out_doc, TARGET_SIZE)
# ページをグループとしてコピー
group = Group.copy_from_page(out_doc, in_page, copy_options)
# グループのスケーリングと位置を計算
scale = min(TARGET_SIZE.width / rotated_size.width, TARGET_SIZE.height / rotated_size.height)
# 位置を計算
position = Point(
x=(TARGET_SIZE.width - page_size.width * scale) / 2,
y=(TARGET_SIZE.height - page_size.height * scale) / 2,
)
# コンテンツジェネレータを作成
with ContentGenerator(out_page.content, False) as generator:
# 変換を計算して適用
transform = AffineTransform.get_identity()
transform.translate(position.x, position.y)
transform.scale(scale, scale)
# 入力ファイルを回転
if rotate:
center_point = Point(x=page_size.width / 2, y=page_size.height / 2)
transform.rotate(90, center_point)
# グループを描画
generator.transform(transform)
generator.paint_group(group, None, None)
# 出力ドキュメントにページを追加
out_doc.pages.append(out_page)
# グローバル変数を定義
TARGET_SIZE = Size(width=595, height=842) # A4 portrait
ALLOW_ROTATE = True
# 入力PDFを開く
with io.FileIO(input_file_path, "rb") as in_stream:
with Document.open(in_stream, None) as in_doc:
# 出力PDFを生成
with io.FileIO(output_file_path, "wb+") as out_stream:
with Document.create(out_stream, in_doc.conformance, None) as out_doc:
# ドキュメント全体のデータをコピー
copy_document_data(in_doc, out_doc)
# ページの処理とサイズ変更
scale_pages_to_fit(in_doc, out_doc)
PDFの指定されたページを90度回転します。
// 入力PDFを開く
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
szInPath, szErrorBuff, Ptx_GetLastError());
// 出力PDFを生成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
szOutPath, szErrorBuff, Ptx_GetLastError());
// ドキュメント全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// ページのコピーオプションを設定
pCopyOptions = PtxPdf_PageCopyOptions_New();
// 全てのページをコピー
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// 指定されたページを90度回転
for (int i = 0; i < ARRAY_SIZE(aPageNumbers); i++)
{
pOutPage = PtxPdf_PageList_Get(pCopiedPages, aPageNumbers[i] - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to get copied page. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_Rotate(pOutPage, ePtxGeom_Rotation_Clockwise),
_T("Failed to rotate page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
}
// 出力文書にページを追加
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages),
_T("Failed to add copied pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// ビュワー設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
// 入力PDFを開く
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// 出力PDFを生成
using (Stream outFs = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outFs, inDoc.Conformance, null))
{
// ドキュメント全体のデータをコピー
CopyDocumentData(inDoc, outDoc);
// ページのコピーオプションを定義
PageCopyOptions copyOptions = new PageCopyOptions();
// 全てのページをコピー
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
// 指定されたページを90度回転
foreach (var pageNumber in pageNumbers)
{
copiedPages[pageNumber - 1].Rotate(Rotation.Clockwise);
}
// 出力文書にページを追加
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// ドキュメント全体のデータをコピー
// 出力色特性設定
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// メタデータ
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// ビュワー設定
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// プレーンな埋め込みファイル
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
def copy_document_data(in_doc: Document, out_doc: Document):
# ドキュメント全体のデータをコピー
# 出力色特性設定
if in_doc.output_intent is not None:
in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
# メタデータ
out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
# ビュワー設定
out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
# 関連ファイル(PDF/A-3およびPDF 2.0のみ)
outAssociatedFiles = out_doc.associated_files
for in_file_ref in in_doc.associated_files:
outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
# プレーンな埋め込みファイル
out_embedded_files = out_doc.plain_embedded_files
for in_file_ref in in_doc.plain_embedded_files:
out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
# 入力PDFを開く
with io.FileIO(input_file_path, "rb") as in_stream:
with Document.open(in_stream, None) as in_doc:
# 出力PDFを生成
with io.FileIO(output_file_path, "wb+") as out_stream:
with Document.create(out_stream, in_doc.conformance, None) as out_doc:
# ドキュメント全体のデータをコピー
copy_document_data(in_doc, out_doc)
# ページのコピーオプションを定義
page_copy_options = PageCopyOptions()
# 全てのページをコピー
copied_pages = PageList.copy(out_doc, in_doc.pages, page_copy_options)
# 指定されたページを90度回転
for page_number in page_numbers:
copied_pages[int(page_number) - 1].rotate(Rotation.CLOCKWISE)
# 出力文書にページを追加
out_doc.pages.extend(copied_pages)
PDF4ページを単一ページに配置します。
// 入力PDFを開く
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
szInPath, szErrorBuff, Ptx_GetLastError());
// 出力PDFを生成
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
szOutPath, szErrorBuff, Ptx_GetLastError());
// ドキュメント全体のデータをコピー
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
_T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// ページのコピーオプションを設定
pCopyOptions = PtxPdf_PageCopyOptions_New();
// 全てのページをコピー
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
_T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
_T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
int nPageCount = 0;
for (int iPage = 0; iPage < PtxPdf_PageList_GetCount(pInPageList); iPage++)
{
pInPage = PtxPdf_PageList_Get(pInPageList, iPage);
if (nPageCount == nNx * nNy)
{
// 出力文書に追加
PtxPdfContent_ContentGenerator_Close(pGenerator);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
_T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
Ptx_Release(pOutPage);
pOutPage = NULL;
nPageCount = 0;
}
if (pOutPage == NULL)
{
// 新しい出力ページを作成
pOutPage = PtxPdf_Page_Create(pOutDoc, &PageSize);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage,
_T("Failed to create a new output page. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
TPtxPdfContent_Content* pContent = PtxPdf_Page_GetContent(pOutPage);
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator,
_T("Failed to create content generator. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
}
// グループが存在するエリアを取得
int x = nPageCount % nNx;
int y = nNy - (nPageCount / nNx) - 1;
// セルサイズを計算
TPtxGeomReal_Size cellSize;
cellSize.dWidth = (PageSize.dWidth - ((nNx + 1) * dBorder)) / nNx;
cellSize.dHeight = (PageSize.dHeight - ((nNy + 1) * dBorder)) / nNy;
// セルの位置を計算
TPtxGeomReal_Point cellPosition;
cellPosition.dX = dBorder + x * (cellSize.dWidth + dBorder);
cellPosition.dY = dBorder + y * (cellSize.dHeight + dBorder);
// 入力から出力にページグループをコピー
pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pGroup, _T("Failed to copy page group from input to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
Ptx_GetLastError());
// グループの位置を計算
TPtxGeomReal_Size groupSize;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize),
_T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
double dScale = MIN(cellSize.dWidth / groupSize.dWidth, cellSize.dHeight / groupSize.dHeight);
// ターゲットサイズを計算
TPtxGeomReal_Size targetSize;
targetSize.dWidth = groupSize.dWidth * dScale;
targetSize.dHeight = groupSize.dHeight * dScale;
// 位置を計算
TPtxGeomReal_Point targetPos;
targetPos.dX = cellPosition.dX + ((cellSize.dWidth - targetSize.dWidth) / 2);
targetPos.dY = cellPosition.dY + ((cellSize.dHeight - targetSize.dHeight) / 2);
// 矩形を計算
TPtxGeomReal_Rectangle targetRect;
targetRect.dLeft = targetPos.dX;
targetRect.dBottom = targetPos.dY;
targetRect.dRight = targetPos.dX + targetSize.dWidth;
targetRect.dTop = targetPos.dY + targetSize.dHeight;
// ページにグループを追加
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL),
_T("Failed to paint the group. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (pGroup != NULL)
{
Ptx_Release(pGroup);
pGroup = NULL;
}
if (pInPage != NULL)
{
Ptx_Release(pInPage);
pInPage = NULL;
}
nPageCount++;
}
// 部分的に記入されたページを追加
if (pOutPage != NULL)
{
PtxPdfContent_ContentGenerator_Close(pGenerator);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
_T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
szErrorBuff, Ptx_GetLastError());
Ptx_Release(pOutPage);
pOutPage = NULL;
}
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// 出力色特性設定
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// メタデータ
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
FALSE)
return FALSE;
// ビュワー設定
if (PtxPdf_Document_SetViewerSettings(
pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// プレーンな埋め込みファイル
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(
pOutFileRefList,
PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
// 入力PDFを開く
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
// 出力PDFを生成
using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
PageList outPages = outDoc.Pages;
int pageCount = 0;
ContentGenerator generator = null;
Page outPage = null;
// ドキュメント全体のデータをコピー
CopyDocumentData(inDoc, outDoc);
// 入力ドキュメントからすべてのページをコピー
foreach (Page inPage in inDoc.Pages)
{
if (pageCount == Nx * Ny)
{
// 出力文書に追加
generator.Dispose();
outPages.Add(outPage);
outPage = null;
pageCount = 0;
}
if (outPage == null)
{
// 新しい出力ページを作成
outPage = Page.Create(outDoc, PageSize);
generator = new ContentGenerator(outPage.Content, false);
}
// グループが存在するエリアを取得
int x = pageCount % Nx;
int y = Ny - (pageCount / Nx) - 1;
// セルサイズを計算
Size cellSize = new Size
{
Width = (PageSize.Width - ((Nx + 1) * Border)) / Nx,
Height = (PageSize.Height - ((Ny + 1) * Border)) / Ny
};
// セルの位置を計算
Point cellPosition = new Point
{
X = Border + x * (cellSize.Width + Border),
Y = Border + y * (cellSize.Height + Border)
};
// ページのコピーオプションを定義
PageCopyOptions copyOptions = new PageCopyOptions();
// 入力から出力にページグループをコピー
Group group = Group.CopyFromPage(outDoc, inPage, copyOptions);
// グループの位置を計算
Size groupSize = group.Size;
double scale = Math.Min(cellSize.Width / groupSize.Width,
cellSize.Height / groupSize.Height);
// ターゲットサイズを計算
Size targetSize = new Size
{
Width = groupSize.Width * scale,
Height = groupSize.Height * scale
};
// 位置を計算
Point targetPos = new Point
{
X = cellPosition.X + ((cellSize.Width - targetSize.Width) / 2),
Y = cellPosition.Y + ((cellSize.Height - targetSize.Height) / 2)
};
// 矩形を計算
Rectangle targetRect = new Rectangle
{
Left = targetPos.X,
Bottom = targetPos.Y,
Right = targetPos.X + targetSize.Width,
Top = targetPos.Y + targetSize.Height
};
// ページにグループを追加
generator.PaintGroup(group, targetRect, null);
pageCount++;
}
// ページを追加
if (outPage != null)
{
generator.Dispose();
outPages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// ドキュメント全体のデータをコピー
// 出力色特性設定
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// メタデータ
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// ビュワー設定
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// 関連ファイル(PDF/A-3およびPDF 2.0のみ)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// プレーンな埋め込みファイル
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
def copy_document_data(in_doc: Document, out_doc: Document):
# ドキュメント全体のデータをコピー
# 出力色特性設定
if in_doc.output_intent is not None:
in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
# メタデータ
out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
# ビュワー設定
out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
# 関連ファイル(PDF/A-3およびPDF 2.0のみ)
outAssociatedFiles = out_doc.associated_files
for in_file_ref in in_doc.associated_files:
outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
# プレーンな埋め込みファイル
out_embedded_files = out_doc.plain_embedded_files
for in_file_ref in in_doc.plain_embedded_files:
out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
# グローバル変数定義
nx = 2
ny = 2
page_size = Size(595.0, 842.0) # A4 portrait
border = 10.0
# 入力PDFを開く
with io.FileIO(input_file_path, 'rb') as in_stream:
with Document.open(in_stream, None) as input_document:
# 出力PDFを生成
with io.FileIO(output_file_path, 'wb+') as output_stream:
with Document.create(output_stream, input_document.conformance, None) as output_document:
out_pages = output_document.pages
page_count = 0
generator = None
out_page = None
# ドキュメント全体のデータをコピー
copy_document_data(input_document, output_document)
# 入力ドキュメントからすべてのページをコピー
for in_page in input_document.pages:
if page_count == nx * ny:
# Add to output document
generator.__exit__(None, None, None)
out_pages.append(out_page)
out_page = None
page_count = 0
if out_page is None:
# Create a new output page
out_page = Page.create(output_document, page_size)
generator = ContentGenerator(out_page.content, False)
# グループが存在するエリアを取得 (//floorでの除算)
x = int(page_count % nx)
y = int(ny - (page_count // nx) - 1)
# セルサイズを計算
cell_width = (page_size.width - ((nx + 1) * border)) / nx
cell_height = (page_size.height - ((ny + 1) * border)) / ny
# セルの位置を計算
cell_x = border + x * (cell_width + border)
cell_y = border + y * (cell_height + border)
# ページのコピーオプションを定義
copy_options = PageCopyOptions()
# 入力から出力にページグループをコピー
group = Group.copy_from_page(output_document, in_page, copy_options)
# グループの位置を計算
group_size = group.size
scale = min(cell_width / group_size.width, cell_height / group_size.height)
# Compute target size
target_width = group_size.width * scale
target_height = group_size.height * scale
# ターゲットサイズを計算
target_x = cell_x + ((cell_width - target_width) / 2)
target_y = cell_y + ((cell_height - target_height) / 2)
# 矩形サイズを計算
target_rect = Rectangle()
target_rect.left = target_x
target_rect.bottom = target_y
target_rect.right = target_x + target_width
target_rect.top = target_y + target_height
# ページにグループを追加
generator.paint_group(group, target_rect, None)
page_count += 1
# ページを追加
if out_page:
generator.__exit__(None, None, None)
out_pages.append(out_page)
他の機能サンプルを参照してください。
質問のページからお送りいただくようお願いします。
または、メールでsupport@trustss.co.jpあてにお送りください。
ご購入前の技術的質問も無償で対応します。サポート受付ページからお願いします。