お世話になってます、黒川といいます
PDFファイルから指定ページのイメージ取得や記載内容をテキストで取得
できないかと、Delphi7でPDFiumを使ってみようとしているのですが、
ドキュメント及び指定ページの取得はできているように思えるのですが、
TBitmapに描画させてようとするとEAccessViolationになってしまいます。
呼び出し方が違うのでしょうか?
サンプルコードを記載します。
何かヒントありませんか?
宜しくお願いいたします。
(以下ソース)
UnitMain.pas
unit UnitMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,
UnitPDFiumWrapper;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
procedure RenderPDFToBitmap(const PDFFileName: string);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
FileName : String;
begin
FileName := 'Book1.pdf';
RenderPDFToBitmap(FileName);
end;
procedure TForm1.RenderPDFToBitmap(const PDFFileName: string);
var
PDFium: TPDFium;
Document, Page: Pointer;
PageCount, PageIdx: Integer;
Bitmap: TBitmap;
//
DPI : Integer;
PageW: Double;
PageH: Double;
begin
PDFium := TPDFium.Create;
try
Document := PDFium.LoadDocument(PDFFileName);
if Document = nil then
raise Exception.Create('Failed to load PDF document.');
PageCount := PDFium.GetPageCount(Document);
outputdebugstring(PChar(Format('PDF 全%d頁', [PageCount])));
for PageIdx := 0 to PageCount - 1 do
// for PageIdx := 0 to 0 do
begin
Page := PDFium.LoadPage(Document, PageIdx);
if Page = nil then
raise Exception.CreateFmt('Failed to load page %d.', [PageIdx]);
PageW := PDFium.GetPageWidth(Page);
PageH := PDFium.GetPageHeight(Page);
outputdebugstring(PChar(Format('PDF W%f', [PageW])));
outputdebugstring(PChar(Format('PDF H%f', [PageH])));
//
DPI := 96;
Bitmap := TBitmap.Create;
try
Bitmap.Width := PDFium.PointToPixel(DPI, PageW);
Bitmap.Height := PDFium.PointToPixel(DPI, PageH);
Bitmap.PixelFormat := pf16bit;
PDFium.RenderPageToBitmap(Page, Bitmap); ←この中で
EAccessVioaltion
// ビットマップを表示または保存する処理をここに追加
Bitmap.SaveToFile(Format('Page_%d.bmp', [PageIdx]));
finally
Bitmap.Free;
PDFium.ClosePage(Page);
end;
end;
PDFium.CloseDocument(Document);
finally
PDFium.Free;
end;
end;
end.
UnitPDFiumWrapper.pas
// PDFium.dllの入手先は以下のURLから
// https://github.com/bblanchon/pdfium-binaries
unit UnitPDFiumWrapper;
interface
uses
Windows, SysUtils, Classes, Graphics;
type
TPDFium = class
private
FPDFLibrary: HMODULE;
// 使用する関数
FPDF_LoadDocument : function (file_path: PAnsiChar; password: PAnsiChar): Pointer; cdecl;
FPDF_GetPageCount : function (document: Pointer): Integer; cdecl;
FPDF_LoadPage : function (document: Pointer; page_index: Integer): Pointer; cdecl;
FPDF_RenderPageBitmap : procedure (bitmap: HBITMAP; page: Pointer; start_x, start_y, size_x, size_y, rotate: Integer; flags: Integer); cdecl;
FPDF_CloseDocument : procedure (document: Pointer); cdecl;
FPDF_ClosePage : procedure (page: Pointer); cdecl;
FPDF_InitLibrary : procedure; cdecl;
FPDF_DestroyLibrary : procedure; cdecl;
FPDF_GetPageWidth : function (page: Pointer): double; cdecl;
FPDF_GetPageHeight : function (page: Pointer): double; cdecl;
function LoadPDFium: Boolean;
procedure UnloadPDFium;
public
constructor Create;
destructor Destroy; override;
function PointToPixel(const DPI: Integer; const Value: Extended): Integer;
function LoadDocument(const FileName: string): Pointer;
function GetPageCount(Document: Pointer): Integer;
function LoadPage(Document: Pointer; const PageIdx: Integer): Pointer;
procedure RenderPageToBitmap(Page: Pointer; Bitmap: TBitmap);
procedure CloseDocument(Document: Pointer);
procedure ClosePage(Page: Pointer);
function GetPageWidth(Page: Pointer): Double;
function GetPageHeight(Page: Pointer): Double;
end;
implementation
const
PDFIUM_DLL = 'pdfium.dll';
{ TPDFium }
// PointToPixel
function TPDFium.PointToPixel(const DPI: Integer; const Value: Extended): Integer;
begin
Result := trunc(Value * DPI / 72);
end;
constructor TPDFium.Create;
begin
inherited Create;
if not LoadPDFium then
raise Exception.Create('Failed to load PDFium library.');
if Assigned(FPDF_InitLibrary) then
FPDF_InitLibrary;
end;
destructor TPDFium.Destroy;
begin
if Assigned(FPDF_DestroyLibrary) then
FPDF_DestroyLibrary;
UnloadPDFium;
inherited Destroy;
end;
function TPDFium.LoadPDFium: Boolean;
begin
FPDFLibrary := LoadLibrary(PDFIUM_DLL);
if FPDFLibrary = 0 then
begin
raise Exception.CreateFmt('Failed to load PDFium DLL: %s', [SysErrorMessage(GetLastError)]);
end;
// 関数のアドレスを取得
// FPDF_LoadDocument
@FPDF_LoadDocument := GetProcAddress(FPDFLibrary, 'FPDF_LoadDocument');
if not Assigned(FPDF_LoadDocument) then raise Exception.Create('Failed to get address for FPDF_LoadDocument');
// FPDF_GetPageCount
@FPDF_GetPageCount := GetProcAddress(FPDFLibrary, 'FPDF_GetPageCount');
if not Assigned(FPDF_GetPageCount) then raise Exception.Create('Failed to get address for FPDF_GetPageCount');
// FPDF_LoadPage
@FPDF_LoadPage := GetProcAddress(FPDFLibrary, 'FPDF_LoadPage');
if not Assigned(FPDF_LoadPage) then raise Exception.Create('Failed to get address for FPDF_LoadPage');
// FPDF_RenderPageBitmap
@FPDF_RenderPageBitmap := GetProcAddress(FPDFLibrary, 'FPDF_RenderPageBitmap');
if not Assigned(FPDF_RenderPageBitmap) then raise Exception.Create('Failed to get address for FPDF_RenderPageBitmap');
// FPDF_CloseDocument
@FPDF_CloseDocument := GetProcAddress(FPDFLibrary, 'FPDF_CloseDocument');
if not Assigned(FPDF_CloseDocument) then raise Exception.Create('Failed to get address for FPDF_CloseDocument');
// FPDF_ClosePage
@FPDF_ClosePage := GetProcAddress(FPDFLibrary, 'FPDF_ClosePage');
if not Assigned(FPDF_ClosePage) then raise Exception.Create('Failed to get address for FPDF_ClosePage');
// FPDF_InitLibrary
@FPDF_InitLibrary := GetProcAddress(FPDFLibrary, 'FPDF_InitLibrary');
if not Assigned(FPDF_InitLibrary) then raise Exception.Create('Failed to get address for FPDF_InitLibrary');
// FPDF_DestroyLibrary
@FPDF_DestroyLibrary := GetProcAddress(FPDFLibrary, 'FPDF_DestroyLibrary');
if not Assigned(FPDF_DestroyLibrary) then raise Exception.Create('Failed to get address for FPDF_DestroyLibrary');
// FPDF_GetPageWidth
@FPDF_GetPageWidth := GetProcAddress(FPDFLibrary, 'FPDF_GetPageWidth');
if not Assigned(FPDF_GetPageWidth) then raise Exception.Create('Failed to get address for FPDF_GetPageWidth');
// FPDF_GetPageHeight
@FPDF_GetPageHeight := GetProcAddress(FPDFLibrary, 'FPDF_GetPageHeight');
if not Assigned(FPDF_GetPageHeight) then raise Exception.Create('Failed to get address for FPDF_GetPageHeight');
Result := True;
end;
procedure TPDFium.UnloadPDFium;
begin
if FPDFLibrary <> 0 then
begin
FreeLibrary(FPDFLibrary);
FPDFLibrary := 0;
end;
end;
function AnsiToUtf8(const S: string): AnsiString;
begin
Result := UTF8Encode(S);
end;
function TPDFium.LoadDocument(const FileName: string): Pointer;
begin
if not Assigned(FPDF_LoadDocument) then
raise Exception.Create('FPDF_LoadDocument is not assigned.');
Result := FPDF_LoadDocument(PAnsiChar(AnsiToUtf8(FileName)), nil);
if Result = nil then
raise Exception.Create('Failed to load PDF document. File may be corrupted or incompatible.');
end;
function TPDFium.GetPageCount(Document: Pointer): Integer;
begin
if not Assigned(FPDF_GetPageCount) then
raise Exception.Create('FPDF_GetPageCount is not assigned.');
Result := FPDF_GetPageCount(Document);
end;
function TPDFium.LoadPage(Document: Pointer; const PageIdx: Integer): Pointer;
begin
if not Assigned(FPDF_LoadPage) then
raise Exception.Create('FPDF_LoadPage is not assigned.');
Result := FPDF_LoadPage(Document, PageIdx);
end;
procedure TPDFium.RenderPageToBitmap(Page: Pointer; Bitmap: TBitmap);
begin
if not Assigned(FPDF_RenderPageBitmap) then
raise Exception.Create('FPDF_RenderPageBitmap is not assigned.');
// EAccessViolationが発生する
FPDF_RenderPageBitmap(Bitmap.Canvas.Handle, Page, 0, 0, Bitmap.Width, Bitmap.Height, 0, 0);
end;
procedure TPDFium.CloseDocument(Document: Pointer);
begin
if not Assigned(FPDF_CloseDocument) then
raise Exception.Create('FPDF_CloseDocument is not assigned.');
FPDF_CloseDocument(Document);
end;
procedure TPDFium.ClosePage(Page: Pointer);
begin
if not Assigned(FPDF_ClosePage) then
raise Exception.Create('FPDF_ClosePage is not assigned.');
FPDF_ClosePage(Page);
end;
function TPDFium.GetPageWidth(Page: Pointer): Double;
begin
if not Assigned(FPDF_GetPageWidth) then
raise Exception.Create('FPDF_GetPageWidth is not assigned.');
Result:= FPDF_GetPageWidth(Page);
end;
function TPDFium.GetPageHeight(Page: Pointer): Double;
begin
if not Assigned(FPDF_GetPageHeight) then
raise Exception.Create('FPDF_GetPageHeight is not assigned.');
Result:= FPDF_GetPageHeight(Page);
end;
end.
お世話になります、黒川@Delphi7です。
自己レスです
// EAccessViolationが発生する
FPDF_RenderPageBitmap(Bitmap.Canvas.Handle, Page, 0, 0, Bitmap.Width, Bitmap.Height, 0, 0);
この部分で呼び出していたAPIですが、"FPDF_RenderPage"を使用する事でBitmapが取得できるようになりました。
失礼いたしました
----- Original Message -----
From: "kuro_ml_y2006 via Japan RAD Studio User Group" <radstu...@googlegroups.com>
To: "radstu...@googlegroups.com" <radstu...@googlegroups.com>
Date: 2024/12/11 水 17:47
Subject: [radstudio-jp:462] PDFiumを使ってみたいのですが
--
このメールは Google グループのグループ「Japan RAD Studio User Group」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには radstudio-jp...@googlegroups.com にメールを送信してください。
このディスカッションを表示するには、https://groups.google.com/d/msgid/radstudio-jp/1635018801.9706.1733906855924%40mail.yahoo.co.jp にアクセスしてください。