アイコン 株式会社トラスト・ソフトウェア・システム
電話:03-5316-3375info@trustss.co.jp
電話:03-5316-3375info@trustss.co.jp

開発者向けPDFライブラリ - Pdftools SDK(Toolbox add-on)

PDFを印刷用にレイアウト

PDFを印刷用にレイアウト機能

印刷に適したレイアウトのPDFを作成できます。
フォームフィールドをフラット化したり、ページサイズやページの向きを設定したり、複数のページを1ページに配置したりできます。

ご注意ください:
このAdd-onに印刷機能はありません。
印刷機能はPDF Printer APIで利用できます。

 INFO:
この機能はToolbox add-onの機能ですが、「Pdftools SDK」ライブラリ用のライセンスキーで機能します。
Toolbox add-onの全機能は無償で試用できますが、試用版のライセンスキーが必要です。
試用ライセンスキー要求からご要望ください。

Pdftools SDK 価格見積もり

APIリファレンス (Toolbox Add-on)

Toolbox Add-onのAPIリファレンスはこちらです。(すべて英文)

サンプル

C#のサンプルプロジェクトではPdftools SDK(Toolbox Add-on)ライブラリ(DLL)をNuGetから自動でダウンロードします。
CのサンプルプロジェクトにはPdftools SDK(Toolbox Add-on)ライブラリ(DLL)が含まれています。

 
Toolbox add-onの全機能は無償で試用できますが、試用版(無料)のライセンスキーが必要です。
試用ライセンスキー要求からご要望ください。

License Agreement(利用許諾契約書)が含まれていますので必ず確認してください。


フォームフィールドをフラット化

このプロジェクトでは、フォームフィールドをその視覚的な外観を維持しながら非インタラクティブなコンテンツに変換します。

フォームフィールドをフラット化

フォーム フィールドの外観をフラット化し、すべてのインタラクティブな要素を破棄します。


サンプル・プロジェクト(C)をダウンロード
サンプル・プロジェクト(C#)をダウンロード
サンプル・プロジェクト(Python)をダウンロード
サンプル・プロジェクトをダウンロード
サンプル・プロジェクトの実行手順を参照してください
// 入力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の各ページを指定されたのページ形式に適合させます。


サンプル・プロジェクト(C)をダウンロード
サンプル・プロジェクト(C#)をダウンロード
サンプル・プロジェクト(Python)をダウンロード
サンプル・プロジェクトをダウンロード
サンプル・プロジェクトの実行手順を参照してください
// 入力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度回転します。


サンプル・プロジェクト(C)をダウンロード
サンプル・プロジェクト(C#)をダウンロード
サンプル・プロジェクト(Python)をダウンロード
サンプル・プロジェクトをダウンロード
サンプル・プロジェクトの実行手順を参照してください
// 入力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)

複数のページを1ページにまとめる

複数のページを1ページに配置する

PDF4ページを単一ページに配置します。


サンプル・プロジェクト(C)をダウンロード
サンプル・プロジェクト(C#)をダウンロード
サンプル・プロジェクト(Python)をダウンロード
サンプル・プロジェクトをダウンロード
サンプル・プロジェクトの実行手順を参照してください
// 入力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あてにお送りください。


ご購入前の技術的質問も無償で対応します。サポート受付ページからお願いします。

> PDF Structure (PDF構成)

> PDF Imager-LP (画像化)

> PDF Stamper (電子印鑑)

> Pdftools SDK

- サンプル・コード
- Pdftools SDKサンプルの利用手順
- Toolbox Add-on
- Toolbox Add-onサンプルの利用手順
> Pdftools SDK APIリファレンス
- その他のAPI及びコマンドラインツール
> PDF SDK オープンソースと有償ライブラリ