PDF文書をページ単位にバラしてJPEG画像に変換するVBOを作りました。 #blueprism

# やりたいこと
PDFを1ページずつバラして画像にしたい。
DXを探しても、Excel→PDFとか、画像→PDFとか、惜しいのはあるんだけどこれは無い。
将来的に掲載されるかもしれんけどたぶん有料アセットになりそう（BP社は最近そういう傾向ですねー）。
# なんでそんなことがしたいのか
たとえば
+ Web掲載用などで、PDF文書のサムネイル画像がほしい
+ [アップロードできる画像の形式はなんですか？ (DXSuite)](https://help-dxsuite.inside.ai/hc/ja/articles/7926962917785-%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E3%81%8D%E3%82%8B%E7%94%BB%E5%83%8F%E3%81%AE%E5%BD%A2%E5%BC%8F%E3%81%AF%E3%81%AA%E3%82%93%E3%81%A7%E3%81%99%E3%81%8B) のように、画像に直してから入力しないといけないものがある
+ 電子書籍のビューアで閲覧するため
+ PDFだとテキストをコピペされやすいから画像化したい

など……。
意外とそういう需要はあるんです。
オンラインサービスは手軽だけど、セキュリティやら何やらで業務では使えないことが多いですしね。

# なければ自作
無いものはしょうがない。あれば使う、なければ作る。
お金のある人は、有料アセットが公開されたら金で解決して有料アセットを契約してもいいかも。
有料アセットはBP社のサポートあるし。
他の有料アセットを見てると400ドル/年とかそれくらいが多いみたい。

# 準備
## 必要なDLL
+ PDFiumViewer.dll
[GitHubここです。](https://github.com/pvginkel/PdfiumViewer)NuGetパッケージマネージャでDLLを取ってきて、Blue Prismの実行フォルダに配置してください。

+ pdfium.dll
[PDFium](https://www.nuget.org/packages/PDFium.WindowsV2)というのがGitHubにあって、これをNuGetパッケージマネージャで開くと、「pdfium_x86.dll」「pdfium_x64.dll」の2個が入っています。
両方Blue Prismの実行フォルダに配置して、どっちかを「pdfium.dll」に改名します。
私の環境では「pdfium_x86.dll」のほうを改名するのが正解でした。
+ System.ValueTuple.dll
.NET4.7以上だと自動で入ります。
Blue Prismのインストール要件が4.7以上なので、つまりBlue Prismが入っていればPCのどこかにあるはず。検索して、Blue Prismの実行フォルダにファイルをコピペしてください。
検索して探し当てた場所に元々あったやつは、そのままそこに置いといてください。
+ PDFiumSharp.dll
どうもこれもないといけないっぽい。[GiuHubここです。](https://github.com/ArgusMagnus/PDFiumSharp)

## グローバルコードオプション
もとからあるやつに追加するぶんです。
上で挙げたDLLをBlue Prismの実行フォルダに配置してからやってください。
### 上のDLLの欄
+ netstandard.dll
+ mscorlib.dll
+ PdfiumViewer.dll
### 下の名前空間の欄
+ System.IO
+ System.Drawing.Imaging
+ PdfiumViewer
# アクション作成
コードステージ1個配置するだけ。
## コードステージの入力引数
pdfPath：変換したいPDF文書ファイルのフルパス。データ型はtext。
outputFolder：変換した画像を格納するフォルダの場所。末尾の「\」要ります。データ型はtext。

出力引数はありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/98685dbd-22a5-b327-62f6-ab8f7a47f11f.png)
## コードステージ
C#で書きました。
最後に「PdfDocumentを明示的に破棄」とやっているのは、BPのコードステージはusingで囲ってもDisposeしてくれないっぽい（PDFファイルを掴んだままになってしまって移動や削除などできなくなってしまう）ので、明示的に書きました。
```Csharp
// PDFを読み込む
using (PdfDocument pdfDocument = PdfDocument.Load(pdfPath))
{
// PDFファイル名から拡張子を除去
string baseFilename = Path.GetFileNameWithoutExtension(pdfPath);

// 各ページをJPGに変換し保存
for (int i = 0; i < pdfDocument.PageCount; i++)
{
    using (Image image = pdfDocument.Render(i, 300, 300, true))
    {
        image.Save(Path.Combine(outputFolder, $"{baseFilename}_{i+1:D3}.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
    }
}

// PdfDocumentを明示的に破棄
if (pdfDocument != null)
{
    pdfDocument.Dispose();
}

}
```
### ファイル名の「$"{baseFilename}_{i+1:D3}.jpg"」の説明
#### ファイル名の頭についてる「$」
[MS Learnの説明はこちらをご覧ください](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/tokens/interpolated)
「文字列補完式」というもので、文字列の中に変数や式の値を埋め込む方法です。
コードの「PDFファイル名から拡張子を除去」というところで定義してるbaseFilename。
たとえばPDF文書が「文書あいうえお.pdf」だったら、baseFilenameは「文書あいうえお」。

#### {i+1:D3}
i：ループカウンタ。forで0から始めてインクリメントしてるやつ。
D：整数
3：最低3桁。たとえば1だったら001。
つまり「{i+1:D3}」は、「i+1」の結果を最低3桁の数字で書いてね、というフォーマット指定子です。
バラしたPDFのページを別々のファイルにするときに、001、002、003…… と、ファイル名の末尾に連番を振れます。

だから、たとえば4ページある「文書あいうえお.pdf」を変換すると、

    文書あいうえお_001.jpg
    文書あいうえお_002.jpg
    文書あいうえお_003.jpg
    文書あいうえお_004.jpg
と4個のjpgファイルが出力されることになります。
# 終わりです
今回もChatGPT大先生にはたいへんお世話になりました。
もう大先生のいない世界では生きていけない……。

あと[Blue Prism Community](https://community.blueprism.com/)。公式コミュニティサイトです。
すごく頼りになります。世界中のいろんな人が助けてくれる。超おすすめ。ただし英語。
Blue Prismユーザでなくてもメアドだけあればアカウントが取れます。メアドはGmailとかでもOK。

将来的には逆パターンも作りたいけど、別のDLLが必要なのでそれは改めて。