// Mit dem folgenden Code kann man den Kontrast einer Bitmap einstellen.

// Getestet mit D4 unter WinME

// Variante 1: Mit Tabelle

type bereich = -100..100; 
 
var 
  kontrast: bereich; 
  original, ergebnis: TBitmap; 
  tbl: array[0..255] of byte; 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  original := TBitmap.create; 
  ergebnis := TBitmap.create; 
  ergebnis.pixelformat := pf24bit; 
end; 
 
procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  ergebnis.free; 
  original.free; 
end; 
 
procedure rechnen; 
var 
  x, z: integer; 
  kontr: double; 
begin 
  kontr := exp((kontrast + 62) / 27) / 10; 
  for x := 0 to 255 do begin 
    z := round((x - 127) * kontr + 127); 
    if z > 255 then z := 255 else 
      if z < 0 then z := 0; 
    tbl[x] := z; 
  end; 
end; 
 
procedure KontrastEinstellen; 
var 
  x, y, b: integer; 
  p1, p2: PBytearray; 
begin 
  b := ergebnis.width * 3 - 1; 
  for y := 0 to ergebnis.height - 1 do begin 
    p1 := original.scanline[y]; 
    p2 := ergebnis.scanline[y]; 
    x := 0; 
    while x < b do begin 
      p2[x] := tbl[p1[x]]; 
      p2[x + 1] := tbl[p1[x + 1]]; 
      p2[x + 2] := tbl[p1[x + 2]]; 
      inc(x, 3); 
    end; 
  end; 
end; 
 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  original.loadfromfile('d:\bilder\frau.bmp'); 
  original.pixelformat := pf24bit; 
  ergebnis.width := original.width; 
  ergebnis.height := original.height; 
  kontrast := 25; // z.B. 
  rechnen; 
  KontrastEinstellen; 
  canvas.draw(0, 0, ergebnis); 
// zur Kontrolle: 
  canvas.draw(original.width + 2, 0, original); 
end;

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


// Variante 2: Direktberechnung

var 
  original: TBitmap; 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  with Trackbar1 do begin 
    min := -100; 
    max := 100; 
    position := 0; 
    Frequency := 10; 
  end; 
  original := TBitmap.create; 
  original.loadfromfile('d:\bilder\haus.bmp'); 
  original.pixelformat := pf24bit; 
  with Image1, Picture.Bitmap do begin 
    autosize := true; 
    pixelformat := pf24bit; 
    width := original.width; 
    height := original.height; 
    canvas.draw(0, 0, original); 
  end; 
end; 
 
procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  original.free; 
end; 
 
procedure kontrast(src, dst: TBitmap; d: double); 
var x, y: integer; 
  ps, pd: PBytearray; 
  function rechnen(b: byte): byte; 
  var h: integer; 
  begin 
    h := trunc(b + (b - 128) * d); 
    if h > 255 then result := 255 
    else if h < 0 then result := 0 
    else result := h; 
  end; 
begin 
  with src do begin 
    for y := 0 to height - 1 do begin 
      ps := scanline[y]; 
      pd := dst.scanline[y]; 
      for x := 0 to width * 3 - 1 do 
        pd[x] := rechnen(ps[x]); 
    end; 
  end; 
end; 
 
procedure TForm1.TrackBar1Change(Sender: TObject); 
begin 
  kontrast(original, image1.picture.bitmap, Trackbar1.position / 100); 
  image1.refresh; 
end;
// --------------------------------------------------------------


// Variante 3: Mittels RGBTriple und dynamischer Tabelle

type 
  Range = -100 .. 500;
procedure Kontrast(const bmp: TBitmap; strength: Range); 
const 
  half = 128; 
var 
  x, y: Integer; 
  pix: PRGBTriple; 
  arr: array of Byte; 
  function boundary(i: Integer): Byte; 
  asm 
    CMP  EAX, $FF 
    JG   @MAX 
    CMP  EAX, 0 
    JGE  @OK 
    MOV  EAX, 0 
    JMP  @OK 
  @MAX: 
    MOV  EAX, $FF 
  @OK: 
  end; 
 begin 
    setlength(arr, 256); 
    for x := 0 to 255 do 
      arr[x] := boundary(Round((x - half) * (strength / 100 + 1)) + half); 
    for y := 0 to pred(bmp.height) do 
    begin 
      pix := bmp.Scanline[y]; 
      for x := 0 to pred(bmp.width) do 
      begin 
        pix.rgbtred := arr[pix.rgbtred]; 
        pix.rgbtblue := arr[pix.rgbtblue]; 
        pix.rgbtgreen := arr[pix.rgbtgreen]; 
        inc(pix); 
      end; 
    end; 
    arr := nil; 
 end;

 


Zugriffe seit 6.9.2001 auf Delphi-Ecke