24.02.2017, Vladimír Klaus, navštíveno 4605x
Nedávno jsem stál před problémem, jak vložit vícestránkové PDF do Wordovského dokumentu tak, aby se ho Word 2016 nesnažil pomocí vestavěného OCR převést na editovatelný text. Jinak řečeno, když už se PDF skládá ze sady obrázků, aby to tak zůstalo. Word je v tomto směru totálně nemožný a OCR vypnout nejde. Tolik úvodem.
Jaké jsou tedy možnosti. Tak jednak se můžete domluvit s tím, kdo připravuje PDF (skenováním dokumentů), aby je neukládal do PDF, ale do TIF. V takovém případě se totiž nabízí čistě Delphi řešení. Základem je využití knihoven GDI+, viz uses. Testovací TIF se dá stáhnout z odkazu na konci článku.
uses GDIPAPI, GDIPOBJ, GDIPUTIL;
procedure TForm1.Button1Click(Sender: TObject);
var
i, pocet: integer;
img: TGPImage;
encoderClsid: TGUID;
begin
//načtu si vícestránkový TIF
img:=TGPImage.Create('d:\multipage_tiff_example.tiff');
//zjistím počet stránek
pocet:=img.GetFrameCount(FrameDimensionPage);
//připravím si "kodér", abych mohl jednotlivé obrázky ukládat jako BMP
GetEncoderClsid ('image/bmp', encoderClsid);
//procházím jednotlivé stránky
for i:=0 to pocet-1 do begin
//nastavím se na danou stránku
img.SelectActiveFrame(FrameDimensionPage, i);
//a tuto stránku uložím
img.Save('d:\pic'+IntToStr(i)+'.bmp', encoderClsid);
end;
img.Free;
ShowMessage('Hotovo');
end;
Jak je vám určitě jasné, v případě PDF tudy cesta nevede, neb PDF není žádný obrázek. Zde se dá ale velmi dobře využít schopnosti IrfanView, který použijeme v dávkovém režimu. A překvapením asi nebude ani to, že IrfanView zvládne takto pracovat nejen s PDF, ale i s TIF soubory.
@echo off
rem Připravíme odkaz na IrfanView
set IV="c:\Program Files (x86)\IrfanView\i_view32.exe"
rem Zavoláme IrfanView, předáme soubor, příkaz extract
rem s cestou a typem souborů a také na závěr ukončení aplikace,
rem protože jinak by se zobrazil i první získaný obrázek
%IV% ukazka.pdf /extract=(d:\,jpg) /cmdexit
rem ...a podobně, resp. úplně stejně použijeme i na TIF
%IV% multipage_tiff_example.tiff /extract=(d:\,jpg) /cmdexit
pause
A proč je tato část uvedena u článku s Delphi. Inu proto, že pomocí Delphi můžeme řídit spouštění IrfanView a to dokonce tak, aby uživatel o ničem nevěděl, resp. aby ho neobtěžovalo vyskakující černé okno s dávkou, ve kterém probíhá extrakce. Navíc do něj může kliknout, zavřít ho apod.
Zde je funkce, kterou používám ke spouštění programů a věřím, že uvedené komentáře budou dostačující k tomu, abyste ji zvládli bez problému použít i pro spuštění IrfanView s příslušnými parametry.
{*----------------------------------------------------------------------
Jednoduché spuštění aplikace nebo zobrazení souboru pomocí
výchozí aplikace. Slouží i k navigování na web atd.
Pozor SW_SHOW může spustit aplikaci i minimalizovanou, pro vynucení
normálního zobrazení je třeba požít SW_SHOWNORMAL, pro skrytou zase
SW_HIDE
-----------------------------------------------------------------------}
procedure SimpleRun (aFileName: string; aParam: string = '';
aShowCmd: integer = SW_SHOW);
var
i: integer;
begin
//pro jistotu se přepnu do adresáře spouštěné aplikace
SetCurrentDirectory(PChar(ExtractFilePath(aFileName)));
//podle toho, jestli to volám s parametrem
if Trim(aParam)<>'' then begin
i:=ShellExecute(0,'open',PChar(aFileName),PChar(aParam),nil,aShowCmd);
end else begin
i:=ShellExecute(0,'open',PChar(aFileName),nil,nil,aShowCmd);
end;
//když se vrátí nízké číslo, jde o nějaký problém - já z toho dělám výjimku
if i<=32 then begin
raise Exception.CreateFmt('ShellExecute result = %d',[i]);
end;
end;
A malá rada na závěr - než se začnete vztekat, že vám to nefunguje, ověřte si, zda PDF/TIF má opravdu více stránek. To, že například ve Photoshopu uložíte dokument s více vrstvami do TIFu (a se zachováním vrstev) neznamená, že se z toho vytvoří vícestránkový soubor. Bohužel.
Zdroje: