LoginSignup
1
3

VSCodeで書く C# × PDFium(PDFiumViewer)

Last updated at Posted at 2022-12-03

前置き

PDFiumはGoogleが作ってオープンソース化したフリーに使えるライブラリです。
C++で作られているのでC#で扱うにはラッパーであるPDFiumViewrを使うといいそうです。
VSCodeではNuGetからパッケージを追加すると使えます。

メイン

・環境

OS: Windows 10 Home
Visual Studio Code バージョン: 1.73.1
言語バージョン: C#10.0
.NETバージョン: .NET 6.0.11

・準備

◆プロジェクトの作成

ソリューションとプロジェクトを作成して開きます。

ターミナル
dotnet new sln -o ./PdfHoge
cd ./PdfHoge
dotnet new console -o ./PdfHoge
dotnet sln add ./PdfHoge/PdfHoge.csproj

◆NuGetパッケージの追加

NuGetからPdfiumViewerと本体であるPdfiumVewer.Native.x86_64.v8-xfa(64bitの場合)を追加します。
バージョンはとりあえず最新。

◇PdfiumViewerの追加

image.png

◇Nativeの追加

image.png

◆ビルド警告の抑制

これまででプログラミングの準備はできていますが、ビルドするとターゲットフレームワーク云々~の警告がでるので、.csprojのPdfiumViewerに「NoWarn="NU1701"」を入れておいて警告を非表示にします。
image.png
image.png

・PDFを読む

サンプルPDFをWordで作りました。↓ これを読んでいきます。
image.png

◆テキストを読む

◇コード

サンプルPDFは.csprojと同じディレクトリに置きました。テキストの読み取りはPdfDocumentクラスGetPdfTextメソッドを使います。引数にはページ番号-1を渡します。結果をみるとフッターが本文より前に来ていたり、タブがなくなってたりしますがおそらくPDFのバイナリはその順序になっているのでしょう。

Program.cs
using PdfiumViewer;
string path = "sample.pdf";
using (PdfDocument doc = PdfDocument.Load(path))
{
    for (var pageNum = 0; pageNum < doc.PageCount; pageNum++)
    {
        string text = doc.GetPdfText(pageNum);
        Console.WriteLine(text);
    }
}
Console.ReadKey();

◇実行結果

image.png

◆画像として保存する

◇Nugetパッケージの追加

JPEGで保存するために、Imageクラスを使います。
Imageクラスを利用するためにSystem.Drawing.CommonをNugetから追加します。
image.png
image.png

◇コード

画像はRenderメソッドで取得します。

Program.cs
using System.Drawing;
using PdfiumViewer;

string path = "sample.pdf";
const int dpi = 96;
const int ppi = 72;
using (PdfDocument doc = PdfDocument.Load(path))
{
    for (var pageNum = 0; pageNum < doc.PageCount; pageNum++)
    {
        SizeF pageSize = doc.PageSizes[pageNum];
        int width = (int) (pageSize.Width * dpi / ppi);
        int height = (int) (pageSize.Height * dpi / ppi);
        Image image = doc.Render(pageNum, width, height, dpi, dpi, false);
        image.Save($"image{pageNum + 1}.jpg");
    }
}

◇実行結果

↓作成されたJPEG画像
image.png

◆WPFのImageで表示する

◇プロジェクトの作成

まずはWPFプロジェクトを追加し、tasks.jsonおよびlaunch.jsonを修正して複数プロジェクトに対応させます。

ターミナル
dotnet new wpf -o PdfHogeWpf
dotnet sln add ./PdfHogeWpf/PdfHogeWpf.csproj

image.png

◇NuGetパッケージの追加

コンソールと同じようにPdfiumViewerとSystem.Drawing.Commonを追加しておき、いったんビルドします。
image.png

◇xamlの編集

MainWindow.xamlにImageコントロールを記述します。ここにPDFの画像を表示させます。
image.png

◇コードビハインドの編集

コードビハインドで画像を流しこみます。

MainWindow.xaml.cs
using System.Drawing;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using PdfiumViewer;

namespace PdfHogeWpf;

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        string path = "sample.pdf";
        const int dpi = 96;
        const int ppi = 72;
        int pageNum = 0;
        BitmapSource bitmapSource;
        using (PdfDocument doc = PdfDocument.Load(path))
        {
            SizeF pageSize = doc.PageSizes[pageNum];
            int width = (int) (pageSize.Width * dpi / ppi);
            int height = (int) (pageSize.Height * dpi / ppi);
            Bitmap bitmap = (Bitmap) doc.Render(pageNum, width, height, dpi, dpi, false);
            nint hBitmap = bitmap.GetHbitmap();
            bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
                hBitmap, 
                nint.Zero, 
                Int32Rect.Empty, 
                BitmapSizeOptions.FromEmptyOptions());
        }
        image.Source = bitmapSource;
        this.Height = bitmapSource.Height;
        this.Width = bitmapSource.Width;
    }
}

◇実行結果

デバッグするとこう
image.png
ざらざらして荒く見えるのは解像度を上げればよくなります。

参考URL

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3