いわゆる自炊した文書をスキャンニングしてPDF化した際、その文章フォーマットに関わらず、そのファイルは左綴じの文書として処理されます。見開きで表示すると、左側に奇数ページ、右側に偶数ページの順に配置されます。
日本語のような縦書き文書の場合、右綴じの文書として処理され、見開き表示では右に奇数ページ、左に偶数ページを配置してほしいところです。
単一のファイルを操作する場合、このための設定変更はファイルのプロパティを変更します。Adobe Acrobatの場合でいうと、トップ画像の赤丸の部分を操作することになる。
一度に複数のファイルについて同様の操作を施す場合、何とか効率化したいところです。ここでは次のツールを活用して、対応方法を紹介します。
VB.Net (Visual Studio 2017 Community)
iText 7
長くなるため、次のエントリーに分割して紹介します。
- 調査:PDFファイルの変更箇所
- 操作:変更操作に対応するiText 7のコード
- 実装1:Visual Studio 2017へのiText 7導入
- 実装2:Visual Studio 2017での実装
この投稿では、「実装2:Visual Studio 2017での実装」を扱います。「実装1:Visual Studio 2017へのiText 7導入」までの準備が完了している前提で進めます。
コーディングの前にプログラム全体の処理手順を考えます。私が前提としているのは、次の事柄です。
前提1 | あるフォルダにpdfを含む、雑多なファイルが格納されている。 |
前提2 | あるフォルダの中にあるpdfだけを処理対象とし、右綴じへ変更する。 |
これを実現するために、次の処理手順を考えました。
処理1 | pdfファイルが格納されているフォルダの選択 Button 1を押下すると、選択されたフォルダがボタンの右に表示される。 |
処理2 | 設定変更されたpdfファイルを格納するフォルダの選択 Button 2を押下すると、選択されたフォルダがボタンの右に表示される。 |
Button 3を押下すると、
処理3 | 処理1内のフォルダにあるpdfファイルの抽出 |
処理4 | 選択されたpdfだけを設定変更する。 |
処理5 | 設定変更したpdfファイルを別のフォルダへ格納する。 |
処理3-5の間、処理対象となったファイル、処理後のファイルをリストボックスに表示します。
フォームの配置と実行後の画面です。実行後の画面では、D:\temp\0917\source配下にあるpdfフォルダが抽出され、D:\temp\0917\destinationへコピーされたことが確認できます。
試みにsource配下にある『影の巡礼者』を開いてみます。ページは左、右の順に配置され、左綴じです。
destination配下にあるファイルを開いてみると、ページは右から左の順に配置され、右綴じに変化していることがわかります。
処理のコードは以下の通りです。必要な方はご参照ください。
GitHubからVB.Netプロジェクトをダウンロードすることもできます。
github.com
Imports iText.Kernel.Pdf Imports System.IO Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load End Sub 'Button 1押下 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Label1.Text = getFolderPath() End Sub 'Button 2:押下 Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Label2.Text = getFolderPath() End Sub 'フォルダの選択 Private Function GetFolderPath() As String If FolderBrowserDialog1.ShowDialog() = DialogResult.OK Then GetFolderPath = FolderBrowserDialog1.SelectedPath Else GetFolderPath = GetFolderPath() End If End Function 'Button 3押下 Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Dim files As IEnumerable(Of String) Dim result As String If IsSameFolder() = False Then files = GetPDFarray(Label1.Text) For Each f As String In files ListBox1.Items.Add(f) result = UpdatePDF(f) ListBox2.Items.Add(result) Next MessageBox.Show("complete") End If End Sub Private Function IsSameFolder() As Boolean If Label1.Text = Label2.Text Then MessageBox.Show("source = destination") IsSameFolder = True Else IsSameFolder = False End If End Function 'フォルダ内のPDFファイルを抽出する。 Private Function GetPDFarray(folder_path As String) As IEnumerable(Of String) Dim search_pattern = "*.pdf" Dim files As IEnumerable(Of String) files = System.IO.Directory.EnumerateFiles(folder_path, search_pattern) GetPDFarray = files End Function 'PDFファイルの設定を変更し、目的のフォルダへコピーする。 Private Function UpdatePDF(source_file As String) As String Dim myReader As New PdfReader(source_file) Dim destination_file As String = Label2.Text + "\" + Path.GetFileName(source_file) Dim myWriter As New PdfWriter(destination_file) Dim myPDF As New PdfDocument(myReader, myWriter) Dim myPreference As New PdfViewerPreferences myPreference.SetDirection(PdfViewerPreferences.PdfViewerPreferencesConstants.RIGHT_TO_LEFT) myPDF.GetCatalog().SetViewerPreferences(myPreference) myPDF.Close() myWriter.Close() myReader.Close() UpdatePDF = destination_file End Function Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click Close() End Sub End Class