以前の記事 に引き続き、 iTextSharp で PDF を回転させます。
事前準備
$PROFILE
と同じディレクトリに用意した lib
に itextsharp.dll を配置し、下記のようにして読み込んでおきます。
Add-Type -Path ($PROFILE | Split-Path -Parent | Join-Path -ChildPath "lib\itextsharp.dll")
コード
function Invoke-PdfRotate {
param(
[parameter(ValueFromPipeline = $true)]$inputObj
,[ValidateSet(90, 180, 270)][int]$clockwise = 180
)
begin {}
process {
$fileObj = Get-Item $inputObj
if ($fileObj.Extension -ne ".pdf") {
Write-Error "Non-pdf file!"
return
}
"rotating clockwise {0} degrees: '{1}'" -f $clockwise, $fileObj.Name | Write-Host -ForegroundColor Cyan
try {
$outFullPath = $fileObj.Directory | Join-Path -ChildPath "rotate$($clockwise)_$($fileObj.Name)"
$pdfReader = New-Object iTextSharp.text.pdf.PdfReader($fileObj.Fullname)
for ($i = 1; $i -le $pdfReader.NumberOfPages; $i++) {
$page = $pdfReader.getPageN($i)
$rotate = $page.getAsNumber([iTextSharp.text.pdf.PdfName]::ROTATE)
$degree = ($rotate)? ($rotate.IntValue + $clockwise) % 360 : $clockwise
$page.put([iTextSharp.text.pdf.PdfName]::ROTATE, [iTextSharp.text.pdf.PdfNumber]::new($degree))
}
$fileStream = New-Object System.IO.FileStream($outFullPath, [System.IO.FileMode]::Create)
$pdfStamper = New-Object iTextSharp.text.pdf.PdfStamper($pdfReader, $fileStream)
$pdfStamper.Close()
$filestream.Close()
$pdfReader.Close()
}
catch {
Write-Error "ERROR: faield to rotate..."
}
}
end {}
}
余談ですが、2番目以降のパラメータを指定するとき先頭にカンマを打つという書き方を見かけて最近マネしています。パラメータ属性が複雑になったときに区切りがハッキリして可読性が上がるような気がします。
使い方
ファイルをパイプもしくは -inputObj
パラメータで渡します。回転方向は時計回りに90度・180度・270度から選択できるようにしました。
# パラメータに渡す
> Invoke-PdfRotate -inputObj .\hoge.pdf
# パイプで渡す
> ls -file | Invoke-PdfRotate -clockWise 90
仕事場の複合機が不調だと紙詰まりが頻繁に発生します。回避のためにホチキス跡のない側からフィーダーに通すのですが、その結果生じる「上下逆転したスキャン PDF を逐一手作業で回転させる仕事」をなくせないかと考えたコマンドです。
回転機能は複合機側に付いていてほしいですね……。