// Eine Bitmap wird in Mosaiksteine zerlegt.

 // Getestet mit D4 unter XP
 

Original Variante 1
Faktor 4
Variante 2
Mosaiksteingröße 4
ohne Schattierung
(waagerecht 0
senkrecht 0)
Variante 2
Mosaiksteingröße 4
mit Schattierung
(waagerecht -45
senkrecht +45)


// Variante 1: Einfacher Code

function mosaik(source, dest: TBitmap; faktor: byte): boolean; 
var hlp: TBitmap; 
begin 
  result := false; 
  if (faktor < 3) or (faktor > source.width div 2) 
    or (faktor > source.height div 2) then exit; 
  hlp := TBitmap.create; 
  hlp.width := source.width div faktor; 
  hlp.height := source.height div faktor; 
  hlp.canvas.stretchdraw(rect(0, 0, hlp.width, hlp.height), source); 
  dest.width := source.width; 
  dest.height := source.height; 
  dest.canvas.stretchdraw(rect(0, 0, dest.width, dest.height), hlp); 
  hlp.free; 
  result := true; 
end; 
 
 
// Beispielaufruf 
procedure TForm1.Button1Click(Sender: TObject); 
var bm: TBitmap; 
begin 
  bm := TBitmap.create; 
  if not 
    mosaik(Image1.picture.bitmap, bm, 4) 
    then showmessage('Fehler') else 
    canvas.draw(Image1.left, Image1.top, bm); 
  bm.free; 
end; 

// -------------------------------------------------------------------
 

// Variante 2:

// Das Bild wird bei Bedarf in der Größe so angepasst, dass alle Mosaiksteine
// in voller Größe dargestellt werden können. Mit den Variablen "
waagerecht"
// und "
senkrecht" kann eine waagerecht und/oder senkrecht verlaufende
// Aufhellung bzw. Abdunkelung der einzelnen Mosaiksteine erreicht werden,
// was das Mosaik plastischer erscheinen läßt.

procedure mosaik(src: TGraphic; dest: TBitmap; 
  steingrsse: byte; waagerecht, senkrecht: integer; anpassen: boolean); 
var x, y, s3, b3: integer; 
  ww, ws: single; 
  function addieren(b: byte; i, j: integer): byte; 
  var h: integer; 
  begin 
    h := trunc(b + i * ww + j * ws); 
    if h < 0 then result := 0 else 
      if h > 255 then result := 255 
      else result := h; 
  end; 
  procedure makesteingrsse(i, j: integer); 
  var w, h, k: integer; 
    p: pbytearray; 
    r, g, b: byte; 
  begin 
    r := 127; 
    g := r; 
    b := r; 
    for h := 0 to steingrsse - 1 do 
      if j + h < dest.height then begin 
        w := 0; 
        p := dest.scanline[j + h]; 
        while w < s3 do begin 
          k := i + w; 
          if k >= b3 then break; 
          b := (p[k] + b) div 2; 
          g := (p[k + 1] + g) div 2; 
          r := (p[k + 2] + r) div 2; 
          inc(w, 3); 
        end; 
      end; 
    for h := 0 to steingrsse - 1 do 
      if j + h < dest.height then begin 
        w := 0; 
        p := dest.scanline[j + h]; 
        while w < s3 do begin 
          k := i + w; 
          if k >= b3 then break; 
          p[k] := addieren(b, w, h); 
          p[k + 1] := addieren(g, w, h); 
          p[k + 2] := addieren(r, w, h); 
          inc(w, 3); 
        end; 
      end; 
  end; 
begin 
  dest.pixelformat := pf24bit; 
  if anpassen then begin 
    dest.width := ((src.width + steingrsse) div steingrsse) * steingrsse; 
    dest.height := ((src.height + steingrsse) div steingrsse) * steingrsse; 
  end else begin 
    dest.width := src.width; 
    dest.height := src.height; 
  end; 
  dest.canvas.stretchdraw(dest.canvas.cliprect, src); 
  s3 := steingrsse * 3; 
  b3 := dest.width * 3; 
  if waagerecht = 0 then ww := 0 else 
    ww := ((waagerecht * 0.67) / (steingrsse * 3)); 
  if senkrecht = 0 then ws := 0 else 
    ws := (senkrecht / (steingrsse * 3)); 
  for y := 0 to dest.height div steingrsse do 
    for x := 0 to b3 div steingrsse do 
      makesteingrsse(x * s3, y * steingrsse); 
end; 
 
// Beispielaufruf 
 
procedure TForm1.Button2Click(Sender: TObject); 
var 
  bm: TBitmap; 
begin 
  bm := TBitmap.create; 
  mosaik(Image1.picture.graphic, bm, 4, -45, 45, true); 
  canvas.draw(Image1.left + Image1.width, Image1.top, bm); 
  bm.free; 
end;



Zugriffe seit 6.9.2001 auf Delphi-Ecke