24.02.2017, Vladimír Klaus, navštíveno 4616x

Delphi
Grafika

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.

Delphi - jak získat obrázky z vícestrákových TIF nebo PDF souborů

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: