PowerShellからPDFSharpを呼び出してPDFをPocketMod形式にレイアウトし直します。
オリジナル(拙作)は
https://qiita.com/acknpop/items/dd03f9e9df18eb05b18c
ですが、iTextSharpの利用が信条的に受け入れがたい人のために。
下準備
まず始めに pdfsharp.dll を入手してください。
nugetするのが本筋ですが、下記はスクリプトを置くフォルダにlibというサブフォルダを作って、その下に pdfsharp.dll を入れる方式です。
普通はInstall-Moduleして、Get-Moduleで使うはず。
スクリプト
以下を ConvertTo-PocketMod.ps1 として保存。
# Convert PDF To PocketMod style
param(
[parameter(mandatory=$true)][string]$sourceDataPath,
[parameter(mandatory=$true)][string]$destinationPath
)
function ConvertTo-PocketMod($sourceDataPath, $destinationPath)
{
# path of pdfsharp.dll
[System.Reflection.Assembly]::LoadFrom((Join-Path (Split-Path $script:MyInvocation.MyCommand.Path) "\lib\PdfSharp.dll")) | Out-Null
[PdfSharp.Drawing.XPdfForm]$form = [PdfSharp.Drawing.XPdfForm]::FromFile([string]$sourceDataPath)
$pen = New-Object PdfSharp.Drawing.XPen([PdfSharp.Drawing.XColors]::Black, 0.01)
$dash = New-Object PdfSharp.Drawing.XPen([PdfSharp.Drawing.XColors]::Black, 0.01)
$dash.DashPattern = @(300, 300)
try {
# Output page size
$pagesize = [PdfSharp.PageSize]::A4
$doc = New-Object PdfSharp.Pdf.PdfDocument
for($i = 0; $i -lt $form.PageCount; $i++) {
if(($i % 8) -eq 0){
$dst = $doc.AddPage()
$dst.Size = $pagesize
[float]$dw = $dst.Width.Value
[float]$dh = $dst.Height.Value
}
[PdfSharp.Drawing.XGraphics]$gfx = [PdfSharp.Drawing.XGraphics]::FromPdfPage($dst)
$form.PageNumber = $i + 1
[PdfSharp.Pdf.PdfPage]$src = $form.Page
[float]$sw = $src.Width.Value
[float]$sh = $src.Height.Value
if($sw -gt $sh){
$isLandscape = $TRUE
}
else{
$isLandscape = $FALSE
}
if($isLandscape -eq $TRUE){
[float]$scale = $dh / ($sh * 4)
[float]$offset = (($dw / 2) - ($scale * $sw)) / 2
}
else{
[float]$scale = $dh / ( $sw * 4)
[float]$offset = (($dw / 2) - ($scale * $sh)) / 2
}
# Affine translation of PocketMod style
[float]$px = $dw / 2
[float]$py = $dh / 4
[float]$pw = $sw * $scale
[float]$ph = $sh * $scale
$rot = $src.Rotate
if(($isLandscape -eq $TRUE) -or (($rot -eq 90) -or ($rot -eq 270))){
switch($i % 8){
# Left side
# Rotate 180 degrees
0 {
$box = New-Object PdfSharp.Drawing.XRect(-($px - $offset), -($py * 1), $pw, $ph)
$gfx.RotateTransform(-180)
}
7 {
$box = New-Object PdfSharp.Drawing.XRect(-($px - $offset), -($py * 2), $pw, $ph)
$gfx.RotateTransform(-180)
}
6 {
$box = New-Object PdfSharp.Drawing.XRect(-($px - $offset), -($py * 3), $pw, $ph)
$gfx.RotateTransform(-180)
}
5 {
$box = New-Object PdfSharp.Drawing.XRect(-($px - $offset), -($py * 4), $pw, $ph)
$gfx.RotateTransform(-180)
}
# Right side
# No rotation
1 {
$box = New-Object PdfSharp.Drawing.XRect(($px + $offset), ($py * 0), $pw, $ph)
}
2 {
$box = New-Object PdfSharp.Drawing.XRect(($px + $offset), ($py * 1), $pw, $ph)
}
3 {
$box = New-Object PdfSharp.Drawing.XRect(($px + $offset), ($py * 2), $pw, $ph)
}
4 {
$box = New-Object PdfSharp.Drawing.XRect(($px + $offset), ($py * 3), $pw, $ph)
}
}
}
else{
switch($i % 8){
# Left side
# Rotate counterclockwise 90 degrees
0 {
$box = New-Object PdfSharp.Drawing.XRect((($py * 0) - $offset), -$px, $pw, $ph)
$gfx.RotateTransform(90)
}
7 {
$box = New-Object PdfSharp.Drawing.XRect((($py * 1) - $offset), -$px, $pw, $ph)
$gfx.RotateTransform(90)
}
6 {
$box = New-Object PdfSharp.Drawing.XRect((($py * 2) - $offset), -$px, $pw, $ph)
$gfx.RotateTransform(90)
}
5 {
$box = New-Object PdfSharp.Drawing.XRect((($py * 3) - $offset), -$px, $pw, $ph)
$gfx.RotateTransform(90)
}
# Right side
# Rotate clockwise 90 degrees
1 {
$box = New-Object PdfSharp.Drawing.XRect(-(($py * 1) + $offset), $px, $pw, $ph)
$gfx.RotateTransform(-90)
}
2 {
$box = New-Object PdfSharp.Drawing.XRect(-(($py * 2) + $offset), $px, $pw, $ph)
$gfx.RotateTransform(-90)
}
3 {
$box = New-Object PdfSharp.Drawing.XRect(-(($py * 3) + $offset), $px, $pw, $ph)
$gfx.RotateTransform(-90)
}
4 {
$box = New-Object PdfSharp.Drawing.XRect(-(($py * 4) + $offset), $px, $pw, $ph)
$gfx.RotateTransform(-90)
}
}
}
$gfx.DrawImage($form, $box)
$gfx.Dispose()
# Draw guide line for folding
if((($i % 8) -eq 7) -or ($i -eq ($form.PageCount - 1))){
[PdfSharp.Drawing.XGraphics]$gfx = [PdfSharp.Drawing.XGraphics]::FromPdfPage($dst)
# draw outside border
$gfx.DrawRectangle($pen, 0, 0, $dw, $dh)
# horizontal lines
$gfx.DrawLine($pen, 0, $dh * 3 / 4, $dw, $dh * 3 / 4)
$gfx.DrawLine($pen, 0, $dh * 2 / 4, $dw, $dh * 2 / 4)
$gfx.DrawLine($pen, 0, $dh * 1 / 4, $dw, $dh * 1 / 4)
# vertical lines
$gfx.DrawLine($pen, $dw / 2, 0, $dw / 2, $dh * 1 / 4)
$gfx.DrawLine($pen, $dw / 2, $dh * 3 / 4, $dw / 2, $dh)
# dashed vertical line
$gfx.DrawLine($dash, $dw / 2, $dh * 1 / 4, $dw / 2, $dh * 3 / 4)
$gfx.Dispose()
}
}
$doc.Save($destinationPath)
}
catch {
Write-Error("Error: " + $_.Exception)
}
}
ConvertTo-PocketMod (Convert-Path $sourceDataPath) $destinationPath
pdfsharp.dllを置いた場所によっては、LoadFromのくだりを書き換える必要があります。
あと、出力ページサイズをA4にハードコーディングしているので、こちらも必要に応じて書き換えてください。
使用例
PowerShellを立ち上げて、
PS> ConvertTo-PocketMod.ps1 元PDFファイル (Join-Path $PWD 出力先PDFファイル)
みたいに使います。
※PowerShellは基本絶対パス指定なので、相対パスを使いたい時はConvert-PathやJoin-Pathを組み合わせるようです
※Convert-Pathは指定したフォルダやファイルが存在しないとエラーになるので注意
あとがき
http://www.pdfsharp.net/
にC#で書かれたSampleがあるので、参考にできるかと。
あと、通常PDFの世界では左下が原点(0,0)なのですが、PDFSharpでは左上が原点になるので要注意。
描画位置合わせは強引にやってるので、あまり参考にはならないかも。