Tipy a triky v Delphi, díl 35.

Dnešní díl se bude zabývat prací s obrázkovými soubory. Ukážeme si, jak je konvertovat na různé formáty, jak udělat inverzní obrázek (negativ), a na závěr si ukážeme, jak měnit rozměry obrázků.

V našem seriálu jsme se doposud zabývali různými tipy ze všech možných oblastí, velká část z nich se týkala například práce se soubory či složkami, takže již máte jistý drobný základ pro vytvoření kupříkladu vlastního jednoduchého souborového manažeru. Po dnešním dílu si budete možná moci vytvořit primitivní prohlížeč obrázků, protože si ukážeme několik základních funkcí s nimi.

Převod souboru BMP do formátu JPEG a naopak

Tento převod je vlastně velmi snadný, ačkoliv se možná na první pohled může zdát opak. Nebudeme totiž všechno od základu programovat sami, což by bylo asi v tomto konkrétním případě nad rámec našeho článku, ale využijeme již funkcí a knihoven, které nám Delphi nabízejí. Hlavní práci v tomto případě tedy udělá knihovna Jpeg, takže ji jako obvykle přidejte do projektu. Pro samotnou konverzi obrázku BMP do formátu JPEG si vytvoříme jednoduchou funkci, jejímiž parametry jsou zdrojový soubor, dále výsledná požadovaná kompresní kvalita souboru JPEG po konverzi a název výstupního souboru. Funkce tedy bude vypadat takto:

procedure BmpToJpeg(Bmp: TBitmap; Q: TJpegQualityRange; var Jpg: TJpegImage);
begin
Jpg.CompressionQuality := Q;
Jpg.Assign(Bmp);
end;

Požadovaná kvalita Q (či chcete-li kompresní faktor), která – jak jistě víte – ovlivňuje výsledný vzhled a velikost souboru, může nabývat hodnot od 1 do 100, přičemž čím nižší je hodnota, tím menší je výsledný soubor (pochopitelně na úkor kvality obrazu). Tuto jednoduchou funkci poté využijeme například takto:

procedure TForm1.Button1Click(Sender: TObject);
var
Bmp : TBitmap;
JPG : TJpegImage;
begin
if Form1.OpenPictureDialog1.Execute then
begin
  Bmp := TBitmap.Create;
  JPG := TJpegImage.Create;
  Bmp.LoadFromFile(Form1.OpenPictureDialog1.FileName);
  BmpToJpeg(Bmp, 30, JPG);
  JPG.SaveToFile(`vystup.jpg`);
  JPG.Free;
  Bmp.Free;
end;
end;

Příklad používá dialog na otevření souboru s obrázkem – OpenPictureDialog, takže jej přidejte na formulář. Jak vidíte, pro jednoduchost je též nastaven napevno název výstupního souboru i jeho kvalita, takže si oba parametry nezapomeňte příslušným způsobem přizpůsobit.

A jak bude vypadat opačná konverze? Velmi podobně a pravděpodobně byste na ni přišli sami, ale pro úplnost zde máte příklad:

procedure JpegToBmp(Jpg: TJpegImage; PF: TPixelFormat; var Bmp: TBitmap);
begin
Bmp.Assign(Jpg);
Bmp.PixelFormat := PF;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
Bmp : TBitmap;
JPG : TJpegImage;
begin
if Form1.OpenPictureDialog1.Execute then
begin
  Bmp := TBitmap.Create;
  JPG := TJpegImage.Create;
  Jpg.LoadFromFile(Form1.OpenPictureDialog1.FileName);
  JpegToBmp(jpg, pf24bit, bmp);
  Bmp.SaveToFile(`vystup.bmp`);
  JPG.Free;
  Bmp.Free;
end;
end;

Ukázku jsme si drobně vylepšili o možnost nastavení požadované barevné hloubky výsledného BMP souboru (viz druhý parametr funkce). V nápovědě naleznete výčet ostatních hodnot, kterých může tato proměnná nabývat, a u samotného typu TBitmap či TJpegImage najdete řadu dalších vlastností a parametrů k experimentování.

Inverze barev bitmapy

K dalším běžným funkcím programů pracujících s obrázky patří funkce invertování obrázku neboli vytvoření negativu. Ukážeme si velmi jednoduchý postup:

procedure TForm1.Button1Click(Sender: TObject);
var
R: TRect;
Bmp: TBitmap;
begin
if Form1.OpenPictureDialog1.Execute then
begin
  Bmp := TBitmap.Create;
  Bmp.LoadFromFile(Form1.OpenPictureDialog1.FileName);
  with Bmp do
  begin
  R := Rect(0, 0, Width, Height);
  InvertRect(Canvas.Handle, R);
  end;
  Bmp.SaveToFile(`inverze.bmp`);
  Bmp.Free;
end;
end;

Opět vidíte, že název výstupního souboru je nastaven pevně, takže si budete muset kód mírně upravit. Když si trochu zaexperimentujete s parametry u funkce Rect (při přiřazování do proměnné R), můžete docílit toho, že invertován bude pouze výřez obrázku, který určíte danými souřadnicemi. Sice mě honem nenapadá, k čemu by se toho dalo v praxi využít, ale ta možnost zde každopádně je.

Změna rozlišení obrázku

I toto je běžná funkce grafických programů či prohlížečů. V našem příkladu si ukážeme konkrétně změnu rozlišení obrázku JPEG, ale postup je samozřejmě obdobný i pro jiné formáty (stejně jako všechny ostatní dnešní příklady). Při změně rozlišení má uživatel obvykle dvě možnosti, jak dosáhnout požadované velikosti. První spočívá v tom, že uživatel přímo zadá rozměry výsledného obrázku v pixelech, kdežto druhou možností je zadat faktor zmenšení/zvětšení například v procentech. Buď pro každý rozměr zvlášť, nebo za současného zachování poměru stran. Všechny příklady mají stejný základ, liší se pouze ve výpočtu výsledných souřadnic. Zde je tedy základní kód:

procedure TForm1.Button1Click(Sender: TObject);
var
Bmp : TBitmap;
Jpg : TJpegImage;
ScaleX, ScaleY : Double;
begin
if Form1.OpenPictureDialog1.Execute then
begin
  Jpg:=TJpegImage.Create;
  try
  Jpg.LoadFromFile(Form1.OpenPictureDialog1.FileName);
  ScaleX := 320 / Jpg.Width;
  ScaleY := 200 / Jpg.Height;
  Bmp := TBitmap.Create;
  try
    Bmp.Width := Round(Jpg.Width * ScaleX);
    Bmp.Height := Round(Jpg.Height * ScaleY);
    Bmp.Canvas.StretchDraw(Bmp.Canvas.Cliprect, Jpg);
    Jpg.Assign(Bmp);
    Jpg.SaveToFile(`resize.jpg`);
  finally
    Bmp.Free;
  end;
  finally
  Jpg.Free;
  end;
end;
end;

V tomto případě dojde ke změně rozlišení na 320x200 pixelů (soubor je opět uložen pod pevně zvoleným názvem).

Jak docílit změny pomocí procent (faktoru zvětšení/zmenšení)? Velice snadno: pouze změníme příslušné řádky, které upravují výsledné koeficienty u jednotlivých rozměrů. Úprava může vypadat například takto:

ScaleX := 0.25;
ScaleY := 0.25;

Zde se jedná o zmenšení obrázku na 25 % původní velikosti, a jelikož jsou pro oba rozměry koeficienty stejné, dojde též k zachování poměru stran. Pokud byste chtěli obě metody zkombinovat, tedy například uživatel určí jeden z rozměrů a vaše aplikace dopočítá rozměr druhý při zachování poměru stran, je výpočet velmi snadný a pravděpodobně jste jej již nyní odvodili sami. Pro úplnost si však uvedeme alespoň variantu, kdy uživatel zadá rozměr X a chce znát příslušné Y:

"Výsledný Rozměr Y" := ("Uživatelem požadovaný rozměr X" / "Původní rozměr X") * "Původní rozměr Y"

Trošku krkolomně zapsáno, to uznávám, ale snad je to dost ilustrativní.

A to je pro dnešek všechno. Příště budeme v tématu pokračovat a ukážeme si další příklady související s prací s grafickými soubory.

Diskuze (3) Další článek: Docházejí zásoby GeForce3

Témata článku: Software, Programování, Původní funkce, Díl, Trik, Požadovaná kvalita, TRI, Základní kód, Běžný převod, DEL


Určitě si přečtěte

Messenger a Instagram přicházejí v Evropě o funkce. Kvůli nové směrnici o soukromí
Vladislav Kluska
EvropaInstagramFacebook Messenger
Finanční správa tento měsíc spustí Moje Daně. Přiznání má být hračka
Lukáš Václavík
eIdentitaČeskoeGovernment
Vážně dnes ještě někdo krade Adobe? Video můžete stříhat zdarma v Resolve a fotky i vektory zvládne Affinity

Vážně dnes ještě někdo krade Adobe? Video můžete stříhat zdarma v Resolve a fotky i vektory zvládne Affinity

** Kde jsou ty doby, kdy měl skoro každý doma Photoshop ** Photoshop a Premiere Pro od kamaráda nebo z warezu ** Dnes už to nemá smysl, existuje totiž hromada laciných alternativ

Jakub Čížek | 92

Jakub Čížek
Grafický editorStřih videa
Microsoft pořád myslí i na odpůrce předplatného. Letos vydá Office 2021
Lukáš Václavík
Microsoft OfficeMicrosoft
Šmírování kamerami Googlu: Koukněte, co se objevilo na Street View

Šmírování kamerami Googlu: Koukněte, co se objevilo na Street View

Google stále fotí celý svět do své služby Street View. A novodobou zábavou je hledat v mapách Googlu vtipné záběry. Podívejte se na výběr nejlepších!

redakce | 4

redakce
Mapy GoogleStreet View
26 užitečných rozšíření pro Chrome: Naučte prohlížeč nové věci

26 užitečných rozšíření pro Chrome: Naučte prohlížeč nové věci

** Prohlížeč Chrome obsahuje širokou škálu funkcí, neumí ale všechno ** Jeho schopnosti můžete rozšířit pomocí rozšíření ** Vybrali jsme pro vás zajímavé a užitečné doplňky

Karel Kilián | 47

Karel Kilián
Doplňky do prohlížečeChromeProhlížeče
Jak najít hranice území obcí a okresů, abyste věděli, kde se můžete pohybovat
Filip KůželJakub Čížek
KoronavirusMapy