8. príklady


Posledná zmena: 8.10.2002

Banner Text dvojrozmerné polia, obrázky

Dvojrozmerné polia

výpis dvojrozmerného čísleného poľa

procedúra vypis, ktorá do textovej plochy vypíše obsah dvojrozmerného poľa celých čísel mxn; druhým parametrom procedúry je premená typu TStrings - aby sme ju mohli volať napr. pre Memo1.Lines

- predpokladáme, že Memo - textová plocha má nastavený font "Courier New"

- zarovnaje prvky na šírku 4 znaky, napr.

   1  17 106   6   8 100
  11  13   2  14   2 106
 108  11 104  10 101 106
   5  10  14   7 105   8
 107   8 103 110  15 107

const
  m=5; n=6; sirka=4;

type
  pole = array[1..m,1..n] of integer;

procedure vypis(const p:pole; t:TStrings);
var
  i,j:integer;
  s,s1:string;
begin
  t.Clear;
  for i:=1 to m do begin
    s:='';
    for j:=1 to n do begin
      s1:='       '+IntToStr(p[i,j]);
      s:=s+copy(s1,length(s1)-sirka+1,maxint);
    end;
    t.Add(s);
  end;
end;

očíslovanie prvkov poľa

zaplňte dvojrozmerné pole mxn postupne po riadkoch číslami 1..m*n

   1   2   3   4   5   6
   7   8   9  10  11  12
  13  14  15  16  17  18
  19  20  21  22  23  24
  25  26  27  28  29  30

var
  p:pole;
  i,j,k:integer;
begin
  k:=1;
  for i:=1 to m do
    for j:=1 to n do begin
      p[i,j]:=k; inc(k);
    end;
  vypis(p,Memo1.Lines);
end;

náhodné hodnoty

zaplňte dvojrozmerné pole mxn náhodne číslami 1..m*n tak, aby v ňom každé číslo bolo práve raz
var
  p:pole;
  i,j,k,pocet:integer;
  h:array[1..m*n] of integer;
begin
  for i:=1 to m*n do h[i]:=i;
  pocet:=m*n;
  for i:=1 to m do
    for j:=1 to n do begin
      k:=random(pocet)+1;
      p[i,j]:=h[k];
      h[k]:=h[pocet]; dec(pocet);
    end;
  vypis(p,Memo1.Lines);
end;

zapĺňanie šikmo

zaplňte dvojrozmerné pole mxn postupne číslami 1..m*n - šikmo, napr.

   1   2   4   7  11  16
   3   5   8  12  17  21
   6   9  13  18  22  25
  10  14  19  23  26  28
  15  20  24  27  29  30

var
  p:pole;
  i,j,k:integer;
begin
  k:=1;
  for i:=1 to m+n do
    for j:=1 to i do
      if (j<=m) and (i-j+1<=n) then begin
        p[j,i-j+1]:=k; inc(k);
      end;
  vypis(p,Memo1.Lines);
end;

Ďalšie úlohy

  • zaplňte prvky obdĺžnikovej tabuľky M x N číslami 1..mxn v poradí v akom ležia na špirále vedúcej z ľavého horného rohu do stredu

Obrázok ako dvojrozmerné pole farebných bodov - pixelov

  • vo formulári máme dve grafické plochy Image1 a Image2 - sú rovnako veľké - štvorcové, napr. 250x250
  • v Image1 už máme načítanú nejakú bitmapu, napr. pomocou Image1.Picture.LoadFromFile("tiger.bmp")

otočenie vpravo

do Image2 sa prekopíruje Image1 otočený o 90 stupňov vpravo (v smere otáčania hodinových ručičiek)
var
  g1,g2:TCanvas;
  x,y,w:integer;
begin
  g1:=Image1.Canvas; g2:=Image2.Canvas;
  w:=Image1.Width;
  for y:=0 to w-1 do begin
    for x:=0 to w-1 do
      g2.Pixels[w-y-1,x]:=g1.Pixels[x,y];
    //g2.Pixels[y,w-x-1]:=g1.Pixels[x,y];//otoč vľavo
    Image2.Repaint;
  end;
end;

otáčanie na mieste

otočte Image1 na mieste - bez pomocného Image a bez poľa

- obrázok rozdelíme uhlopriečkami na štyri kvadranty

- každý bod z jedného kvadrantu - postupne otočíme o 90 stupňov, t.j. naraz otočíme 4 symetrické body

var
  g:TCanvas;
  x,y,w:integer;
  c:TColor;
begin
  g:=Image1.Canvas; w:=Image1.Width;
  for y:=0 to w div 2-1 do begin
    for x:=y to w-y-2 do begin
      c:=g.Pixels[x,y];
      g.Pixels[x,y]:=g.Pixels[w-y-1,x];
      g.Pixels[w-y-1,x]:=g.Pixels[w-x-1,w-y-1];
      g.Pixels[w-x-1,w-y-1]:=g.Pixels[y,w-x-1];
      g.Pixels[y,w-x-1]:=c;
    end;
    Image1.Repaint;
  end;
end;

zvlnený obrázok

prekopírujte obrázok z Image1 do Image2 tak, že každý riadok je posunutý o upravenú funkciu sínus, napr.

var
  g1,g2:TCanvas;
  x,y,posun,w:integer;
begin
  g1:=Image1.Canvas; g2:=Image2.Canvas;
  w:=Image1.Width;
  for y:=0 to w-1 do begin
    posun:=round(10*sin(y*pi/30));
    for x:=0 to w-1 do
      g2.Pixels[x+posun,y]:=g1.Pixels[x,y];
    Image2.Repaint;
  end;
end;

obrázok do textového súboru

vytvorte textový súbor, ktorý bude v každom riadku obsahovať farby bodov riadka obrázku (TColor sú vlastne integer)
var
  g:TCanvas;
  x,y:integer;
  t:TextFile;
begin
  g:=Image1.Canvas;
  AssignFile(t,'tiger.txt'); Rewrite(t);
  for y:=0 to Image1.Height-1 do begin
    for x:=0 to Image1.Width-1 do
      write(t,g.Pixels[x,y],' ');
    writeln(t);
  end;
  CloseFile(t);
end;

obrázok z textového súboru

zobrazte obrázok uložený v textovom súbore
var
  g:TCanvas;
  x,y,f:integer;
  t:TextFile;
begin
  AssignFile(t,'tiger.txt'); Reset(t);
  g:=Image2.Canvas; y:=0;
  while not seekeof(t) do begin
    x:=0;
    while not seekeoln(t) do begin
      read(t,f); g.Pixels[x,y]:=f; inc(x);
    end;
    readln(t); Image2.Repaint; inc(y);
  end;
  CloseFile(t);
end;

rozštvrtenie obrázka

obrázok z Image1 zmenšíme na štvrtinu a štyrikrát prekopírujeme do Image2; každá takáto štvrtina bude obsahovať iné bodky z pôvodného obrázka, t.j. z pôvodného obrázka zoberieme štvorice bodov 2x2 a každú z týchto bodiek rozdelíme do inej štvrtiny, napr.

var
  g1,g2:TCanvas;
  x,y,xx,yy,w,w2:integer;
begin
  g1:=Image1.Canvas; g2:=Image2.Canvas;
  w:=Image1.Width; w2:=w div 2;
  for y:=0 to w-1 do begin
    for x:=0 to w-1 do begin
      xx:=x div 2+x mod 2*w2;
      yy:=y div 2+y mod 2*w2;
      g2.Pixels[xx,yy]:=g1.Pixels[x,y];
    end;
    Image2.Repaint;
  end;
end;

úprava RGB

prekopírujte obrázok z Image1 do Image2 tak, že pritom sa z farby každej bodky najprv vyrobí trojica zložiek RGB a potom sa v každej zložke vynulujú spodné 4 bity (napr. r div 16*16)

vizuálne porovnajte oba obrázky

var
  g1,g2:TCanvas;
  x,y,w:integer;
  r,g,b:byte;
  f:TColor;
begin
  g1:=Image1.Canvas; g2:=Image2.Canvas;
  w:=Image1.Width;
  for y:=0 to w-1 do begin
    for x:=0 to w-1 do begin
      f:=g1.Pixels[x,y]; r:=GetRValue(f);
      g:=GetGValue(f); b:=GetBValue(f);
      r:=r div 16*16; g:=g div 16*16; b:=b div 16*16;
      g2.Pixels[x,y]:=RGB(r,g,b);
    end;
    Image2.Repaint;
  end;
end;

Ďalšie úlohy

  • posledný príklad môžete využiť tak, že do obrázka zakódujete nejaký textový súbor: v každej zložke RGB najprv vynulujete 4 spodné bity a potom sem vložíte 4 bity z textového súboru - každý bajt súboru sa postupne rozdelí na dva polbajty (4 bajty): bajt div 16 a bajt mod 16
  • podobne sa dá zakódovať do voľných polbajtov aj úplne iný obrázok: do každého RGB (do jeho spodných polbajtov) každého pixelu vložíme horné 4 bity obrázka - najlepšie rovnakého rozmeru (pokúste sa touto metódou odhaliť, aký obrázok je ukrytý v tiger2.bmp)
  • aj ideu rozštvrtenia obrázka niekedy môžeme považovať za zakódovanie: naprogramujte opačnú metódu k rozštvrťovaniu - z každej štvrtiny sa postupne skladajú zodpovedajúce pixely; ak by sme ale nemali rozštvrtený jeden obrázok, ale napr. štyri rôzne, tak takéto skladanie štvrtín nám tieto štvrtinové obrázky pomieša (pozrite napr. súbor styri.bmp) - obyčajné rozštvrťovanie nám teraz vráti pôvodný stav


© 2002 AB, KVI
blaho@fmph.uniba.sk