könntes du mir evlt. weiter helfen beim "scanline"
ich würde gerne wissen wie ich es am besten einbiden kann, hintergrund sind foglende funktionen die ich von irgenwo her habe wo genau weiß ich leider nicht mehr !
es sind aber halt nicht meine und ich würde sie gerne in meinem paint2 projekt einbinden !
Code: Alles auswählen
unit ucanvasextras;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils,Graphics,types,lcltype,lclintf;
 
implementation
type
  unschaerfe = 0..20;
  ausschlag = -20..20;
  shp = (Diagonal=0, Dreieck=1, Diamant=2, Linse=3);
  rgbarray = array[0..2] of byte;
  argbarray = array of rgbarray;
 
 
procedure farbverlauf
  (bmp:TBitmap;dc: HDC; x, y, breit, hoch: integer; oben, unten: array of TColor);
var
  b1, b2: rgbarray;
  o, u, w, h, j, c, z, fo: integer;
  ao: argbarray;
  au: argbarray;
  p: PBytearray;
  procedure rgbermitteln(at: array of TColor; ar: argbarray; k: integer);
  var i: integer;
  begin
    for i := 0 to k do begin
      at[i] := colortorgb(at[i]);
      ar[i][2] := getrvalue(at[i]);
      ar[i][1] := getgvalue(at[i]);
      ar[i][0] := getbvalue(at[i]);
    end;
  end;
  function rechnen(ar: argbarray): byte;
  begin
    result := trunc(ar[j][z] + (ar[j + 1][z] - ar[j][z]) * (w / fo));
  end;
begin
  bmp.pixelformat := pf24bit;
  o  := high(oben);
  u := high(unten);
  if o = u then begin
    if o > 0 then begin
      bmp.width := breit;
      bmp.height := hoch;
      setlength(ao, o + 1);
      setlength(au, u + 1);
      rgbermitteln(oben, ao, o);
      rgbermitteln(unten, au, u);
      fo := trunc(breit / o + 1) * 3;
      for h := 0 to hoch - 1 do begin
        p := bmp.scanline[h];
        for j := 0 to o do begin
          w := 0;
          while w <= fo - 1 do begin
            c := j * fo + w;
            if c <= breit * 3 - 1 then begin
              for z := 0 to 2 do begin
                b1[z] := rechnen(ao);
                b2[z] := rechnen(au);
                p[c + z] := trunc(b1[z] + (b2[z] - b1[z]) * (h / hoch));
              end;
            end;
            inc(w, 3);
          end;
        end;
      end;
      bitblt(dc, x, y, breit, hoch, bmp.canvas.handle, 0, 0, srccopy);
    end else showmessage('Es müssen mindestens zwei Farben angegeben werden!');
  end else
    showmessage('Die Anzahl der Farben muss oben und unten gleich sein!');
end;
 
procedure farbverlauf1
  (dc: HDC; x, y, breit, hoch: integer; ar: array of TColor; Winkel: Single);
var
  bmp: TBitmap;
  o, w, h, j, c, z, v, br, fo: integer;
  ao: array of array[0..2] of byte;
  p: PBytearray;
  procedure rgbermitteln;
  var
    i: integer;
  begin
    for i := 0 to o do begin
      ar[i] := colortorgb(ar[i]);
      ao[i][2] := getrvalue(ar[i]);
      ao[i][1] := getgvalue(ar[i]);
      ao[i][0] := getbvalue(ar[i]);
    end;
    for i := 0 to 2 do
      ao[o + 1][i] := ao[0][i];
  end;
  function rechnen: byte;
  begin
    result := trunc(ao[j][z] + (ao[j + 1][z] - ao[j][z]) * (w / fo));
  end;
begin
  if (breit > 1) and (hoch > 1) then begin
    if (Winkel >= -45) and (Winkel <= 45) then begin
      o := high(ar);
      if (o > 0) and (o < 8) then begin
        bmp := TBitmap.create;
        bmp.pixelformat := pf24bit;
        Winkel := -Winkel / 45;
        fo := round(breit / o + 1.3333) * 3;
        bmp.width := breit;
        bmp.height := hoch;
        br := breit * 3;
        setlength(ao, o + 2);
        rgbermitteln;
        for h := 0 to hoch - 1 do begin
          p := bmp.scanline[h];
          for j := 0 to o do begin
            w := 0;
            while w < fo do begin
              c := j * fo + w + round(h * Winkel) * 3;
              v := br + fo + o * 3;
              while c < 0 do inc(c, v);
              while c >= v do dec(c, v);
              if c < br then
                for z := 0 to 2 do
                  p[c + z] := rechnen;
              inc(w, 3);
            end;
          end;
        end;
        bitblt(dc, x, y, breit, hoch, bmp.canvas.handle, 0, 0, srccopy);
        bmp.free;
      end else showmessage('Anzahl der Farben ungültig!');
    end else showmessage('Der Winkel muss zwischen -45.0 und +45.0 liegen!');
  end else showmessage('Abmaße zu gering!');
end;
 
 
procedure verlauf(bm: TBitmap; farbe1, farbe2: TColor; art: shp);
var
  x, y, h, w, w3: integer;
  p: pBytearray;
  ri, gi, bi: byte;
  ra, ga, ba: word;
  rd, gd, bd, a, d: single;
begin
  bm.pixelformat := pf24bit;
  if art = Diamant then
    h := bm.height shr 1
  else h := bm.height - 1;
  if art <> Diagonal then
    w := bm.width shr 1 else
    w := bm.width;
  w3 := w * 3;
  farbe1 := colortorgb(farbe1);
  farbe2 := colortorgb(farbe2);
  ra := getrvalue(farbe1);
  ga := getgvalue(farbe1);
  ba := getbvalue(farbe1);
  ri := getrvalue(farbe2);
  gi := getgvalue(farbe2);
  bi := getbvalue(farbe2);
  rd := ri - ra;
  gd := gi - ga;
  bd := bi - ba;
  inc(ra, ra);
  inc(ga, ga);
  inc(ba, ba);
  for y := 0 to h do begin
    p := bm.scanline[y];
    a := y / h;
    if art = Linse then a := sin(pi * a);
    x := 0;
    while x < w3 do begin
      d := a + x / w3;
      p[x] := trunc((ba + bd * d) / 2);
      p[x + 1] := trunc((ga + gd * d) / 2);
      p[x + 2] := trunc((ra + rd * d) / 2);
      inc(x, 3);
    end;
  end;
  if art <> Diagonal then
    stretchblt(bm.canvas.handle, w, 0, w + 1, h + 1,
      bm.canvas.handle, w - 1, 0, -w, h, SRCCOPY);
  if art = Diamant then
    stretchblt(bm.canvas.handle, 0, h + 1, bm.width, h,
      bm.canvas.handle, 0, h, bm.width, -h, SRCCOPY);
end;
 
procedure MosaikVerlauf(bm: TBitmap; F1, F2: TColor;
  stufewaag, stufesenk: byte);
var
  r1, g1, b1: byte;
  vh, vw, uh, uw, fh, fw, i, j: integer;
  rj, gj, bj, ri, bi, gi, drh, dgh, dbh, drw, dgw, dbw: single;
begin
  if (bm.height > 1) and (bm.width > 1) then begin
    if (stufesenk > bm.height) or (stufesenk < 2) then stufesenk := bm.height;
    if (stufewaag > bm.width) or (stufewaag < 2) then stufewaag := bm.width;
    vh := pred(stufesenk);
    vw := pred(stufewaag);
    fh := round(bm.height / stufesenk);
    fw := round(bm.width / stufewaag);
    F1 := ColorToRGB(F1);
    F2 := ColorToRGB(F2);
    r1 := getrvalue(F1);
    g1 := getgvalue(F1);
    b1 := getbvalue(F1);
    drh := (getrvalue(F2) - r1) / vh;
    dgh := (getgvalue(F2) - g1) / vh;
    dbh := (getbvalue(F2) - b1) / vh;
    drw := (getrvalue(F2) - r1) / vw;
    dgw := (getgvalue(F2) - g1) / vw;
    dbw := (getbvalue(F2) - b1) / vw;
    for i := 0 to vw do begin
      ri := r1 + i * drw;
      gi := g1 + i * dgw;
      bi := b1 + i * dbw;
      if i = vw then uw := bm.width else
        uw := succ(i) * fw;
      for j := 0 to vh do begin
        with bm.canvas do begin
          rj := r1 + j * drh;
          gj := g1 + j * dgh;
          bj := b1 + j * dbh;
          brush.color := RGB(round((rj + ri) / 2), round((gj + gi) / 2),
            round((bj + bi) / 2));
          if j = vh then uh := bm.height else
            uh := succ(j) * fh;
          fillrect(rect(i * fw, j * fh, uw, uh));
        end;
      end;
    end;
  end;
end;
 
procedure RotateFont(cnv: TCanvas; Winkel: integer);
var
  Logfont: TLogFont;
begin
  GetObject(cnv.Font.Handle, sizeof(Logfont), @Logfont);
  Logfont.lfEscapement := winkel * 10;
  Logfont.lfOrientation := Logfont.lfEscapement;
  cnv.Font.Handle := CreateFontIndirect(Logfont);
end;
 
procedure WaveTextOut(cnv: TCanvas; x, y: integer;
  amplitude: ausschlag; txt: string);
var
  a, i, j, z, lg: integer;
  s: TSize;
begin
  lg := length(txt);
  if lg = 0 then exit;
  a := abs(amplitude);
  with cnv do begin
    s := TextExtent(txt);
    fillrect(rect(x - 2, y - a, x + s.cx + 2, y + s.cy + a));
    z := y;
    j := 2;
    moveto(x, y);
    for i := 0 to lg - 1 do begin
      if txt[i + 1] <> #32 then
        z := trunc(y + sin(i - j) * amplitude) else inc(j);
      textout(penpos.x, z, txt[i + 1]);
    end;
  end;
end;
 
function SchattenSchrift
  (cnv: TCanvas; txt, fontname: string; fontsize: integer;
  fontstyle: TFontstyles; x, y, xversatz, yversatz: integer;
  fontfarbe: array of TColor; schattenfarbe: TColor;
  unscharf: unschaerfe; var rct: TRect;pbrush:Tbrush): boolean;
var
  sz: TSize;
  bm: TBitmap;
  p: array[0..2] of PBytearray;
  xv, yv, i, j, k, w, z, li, lg, ob, vd2, txtl, txto: integer;
  tempColor,a:Array of TColor;
begin
  result := false;
  lg := length(fontfarbe);
  if lg = 0 then begin
    lg:=length(txt)-1;
    SetLength(tempColor,2);
    for i:=0 to lg do
      tempColor[i]:=rgb(random(255),random(255),random(255));
    a:=tempColor;
  end
  else begin
    SetLength(a,high(fontfarbe)+1);
    for i:=0 to high(fontfarbe) do
    a[i]:=fontfarbe[i];
  end;
 
 
  if (lg = 0) or (txt = '') then exit;
  vd2 := unscharf shr 1;
  xv := abs(xversatz);
  yv := abs(yversatz);
  li := ord(xversatz > 0) * xversatz + vd2 + 1;
  ob := ord(yversatz > 0) * yversatz;
  txtl := 1 + vd2 + ord(xversatz < 0) * xv;
  txto := vd2 + ord(yversatz < 0) * yv;
  dec(x, txtl);
  dec(y, txto);
  bm := TBitmap.create;
  bm.pixelformat := pf24bit;
  with bm.canvas do begin
    font.name := fontname;
    font.color := schattenfarbe;
    font.size := fontsize;
    font.style := fontstyle;
    sz := Textextent(txt);
    bm.width := 1 + unscharf + sz.cx + xv;
    bm.height := 1 + unscharf + sz.cy + yv;
    brush:=pbrush;
    rct := rect(x, y, x + bm.width, y + bm.height);
    bm.canvas.copyrect(rect(0, 0, bm.width, bm.height), cnv, rct);
    textout(li, ob + vd2, txt);
    for k := 1 to unscharf do
      for j := ob + 1 to ob + sz.cy + vd2 do begin
        for w := 0 to 2 do
          p[w] := bm.scanline[j - 1 + w];
        for i := li to li + sz.cx - 1 do begin
          z := i * 3;
          for w := 0 to 2 do
            p[1][z + w] := round((p[0][z + w] + p[2][z + w] +
              p[1][(i - 1) * 3 + w] + p[1][(i + 1) * 3 + w]) / 4);
        end;
      end;
    font.color := a[0];
    textout(txtl, txto, txt[1]);
    for i := 1 to length(txt) - 1 do begin
      if lg > i then font.color := a[i];
      textout(penpos.x, txto, txt[i + 1]);
    end;
  end;
  cnv.draw(x, y, bm);
  bm.free;
  result := true;
end;
 
procedure DrawGradient(ACanvas: TCanvas; Rect: TRect;
  Horicontal: Boolean; Colors: array of TColor);
type
  RGBArray = array[0..2] of Byte;
var
  x, y, z, stelle, mx, bis, faColorsh, mass: Integer;
  Faktor: double;
  A: RGBArray;
  B: array of RGBArray;
  merkw: integer;
  merks: TPenStyle;
  merkp: TColor;
begin
  mx := High(Colors);
  if mx > 0 then
  begin
    if Horicontal then
      mass := Rect.Right - Rect.Left
    else
      mass := Rect.Bottom - Rect.Top;
    SetLength(b, mx + 1);
    for x := 0 to mx do
    begin
      Colors[x] := ColorToRGB(Colors[x]);
      b[x][0] := GetRValue(Colors[x]);
      b[x][1] := GetGValue(Colors[x]);
      b[x][2] := GetBValue(Colors[x]);
    end;
    merkw := ACanvas.Pen.Width;
    merks := ACanvas.Pen.Style;
    merkp := ACanvas.Pen.Color;
    ACanvas.Pen.Width := 1;
    ACanvas.Pen.Style := psSolid;
    faColorsh := Round(mass / mx);
    for y := 0 to mx - 1 do
    begin
      if y = mx - 1 then
        bis := mass - y * faColorsh - 1
      else
        bis := faColorsh;
      for x := 0 to bis do
      begin
        Stelle := x + y * faColorsh;
        faktor := x / bis;
        for z := 0 to 3 do
          a[z] := Trunc(b[y][z] + ((b[y + 1][z] - b[y][z]) * Faktor));
        ACanvas.Pen.Color := RGB(a[0], a[1], a[2]);
        if Horicontal then
        begin
          ACanvas.MoveTo(Rect.Left + Stelle, Rect.Top);
          ACanvas.LineTo(Rect.Left + Stelle, Rect.Bottom);
        end
        else
        begin
          ACanvas.MoveTo(Rect.Left, Rect.Top + Stelle);
          ACanvas.LineTo(Rect.Right, Rect.Top + Stelle);
        end;
      end;
    end;
    b := nil;
    ACanvas.Pen.Width := merkw;
    ACanvas.Pen.Style := merks;
    ACanvas.Pen.Color := merkp;
  end
  else
    // Please specify at least two colors
    raise EMathError.Create('Es müssen mindestens zwei Farben angegeben werden.');
end;
 
end.
ich habe einfach den kommetra durch: property ScanLine[Row: Integer]: Pointer read GetScanLine;