// In einem Bitmap wird eine Farbe gegen eine andere ausgetauscht.

// Getestet mit D4 unter XP

// Methode 1: Für Non-Palette-Bitmaps.
//            Paletten-Bitmaps werden auch unterstützt, aber
//            wenn sich die neue Farbe nicht in der Palette
//            befindet, kommt es zu Farbverfälschungen

procedure ChangeColor(bmp: TBitmap; oldc, newc: TColor); 
var 
  hlp: TBitmap; 
  r: TRect; 
begin 
  hlp := TBitmap.Create; 
  hlp.width := bmp.width; 
  hlp.height := bmp.height; 
  r := rect(0, 0, bmp.width, bmp.height); 
  hlp.canvas.brush.color := newc; 
  hlp.canvas.brushcopy(r, bmp, r, oldc); 
  bmp.canvas.draw(0, 0, hlp); 
  hlp.free; 
end; 

// Beispielaufruf
procedure TForm1.Button4Click(Sender: TObject); 
var 
  bmp: TBitmap; 
begin 
  bmp := TBitmap.Create; 
  bmp.LoadFromFile('d:\bilder\vogel.bmp'); 
  ChangeColor(bmp, clwhite, clred); 
  canvas.draw(0, 0, bmp); 
  bmp.free; 
end; 
 
//----------------------------------------------------------- 
 
// Methode 2: Für Paletten-Bitmaps.
//            Es wird eine Farbe der Palette ausgetauscht, vorausgesetzt
//            die auszutauschende Farbe befindet sich auch wirklich
//            in der Palette.

function ChangePalette(bmp: TBitmap; oldc, newc: TColor): boolean; 
var 
  oldcol: tagPALETTEENTRY; 
  newcol: tagRGBQuad; 
  a: array[0..255] of tagPaletteEntry; 
  x, z: word; 
begin 
  result := false; 
  oldc := colortorgb(oldc); 
  newc := colortorgb(newc); 
  oldcol.peRed := getrvalue(oldc); 
  oldcol.peGreen := getgvalue(oldc); 
  oldcol.peBlue := getbvalue(oldc); 
  newcol.rgbBlue := getbvalue(newc); 
  newcol.rgbGreen := getgvalue(newc); 
  newcol.rgbRed := getrvalue(newc); 
  newcol.rgbReserved := 0; 
  z := GetPaletteEntries(bmp.palette, 0, 256, a); 
  for x := 0 to z - 1 do begin 
    if (oldcol.peRed <> a[x].peRed) 
      or (oldcol.peGreen <> a[x].peGreen) 
      or (oldcol.peBlue <> a[x].peBlue) 
      then continue 
    else begin 
      result := SetDIBColorTable(bmp.Canvas.Handle, x, 1, newcol) <> 0; 
      break; 
    end; 
  end; 
end; 
 
// Beispielaufruf
procedure TForm1.Button6Click(Sender: TObject); 
var 
  bmp: TBitmap; 
begin 
  bmp := TBitmap.Create; 
  bmp.LoadFromFile('d:\bilder\vogel.bmp'); 
  if not 
    ChangePalette(bmp, $FFFFFF, clred) 
    then showmessage('Fehler') else 
    canvas.draw(0, 0, bmp); 
  bmp.Free; 
end; 
 
//----------------------------------------------------------- 
 
// Methode 3: Für Paletten-Bitmaps.
//            Es wird eine Farbe der Palette ausgetauscht. Befindet sich
//            die auszutauschende Farbe nicht in der Palette, wird die
//            Farbe getauscht, welche ihr am nächsten kommt.
  
procedure ChangeNearest(bmp: TBitmap; oldc, newc: TColor); 
var 
  newcol: tagRGBQuad; 
begin 
  oldc := colortorgb(oldc); 
  newc := colortorgb(newc); 
  newcol.rgbBlue := getbvalue(newc); 
  newcol.rgbGreen := getgvalue(newc); 
  newcol.rgbRed := getrvalue(newc); 
  newcol.rgbReserved := 0; 
  SetDIBColorTable(bmp.Canvas.Handle, 
    GetNearestPaletteIndex(bmp.palette, oldc), 1, newcol); 
end; 
 
// Beispielaufruf
procedure TForm1.Button7Click(Sender: TObject); 
var 
  bmp: TBitmap; 
begin 
  bmp := TBitmap.Create; 
  bmp.LoadFromFile('d:\bilder\vogel.bmp');
  ChangeNearest(bmp, $FFFFFE, clred); 
  canvas.draw(0, 0, bmp); 
  bmp.Free; 
end;
//----------------------------------------------------------- 
 
// Methode 4: Für Paletten-Bitmaps.
//            Variante von Methode 3

procedure ChangeNearest2(bmp: TBitmap; oldc, newc: TColor); 
var 
  ms: TMemoryStream; 
  n: array[0..2] of Byte; 
begin 
  newc := colortorgb(newc); 
  oldc := colortorgb(oldc); 
  n[2] := getrvalue(newc); 
  n[1] := getgvalue(newc); 
  n[0] := getbvalue(newc); 
  ms := TMemoryStream.Create; 
  bmp.savetostream(ms); 
  ms.position := 54 + 
    GetnearestPaletteindex(bmp.palette, oldc) * sizeof(TPaletteEntry); 
  ms.writeBuffer(n, 3); 
  ms.position := 0; 
  bmp.loadfromstream(ms); 
  ms.free; 
end; 
 
// Beispielaufruf
procedure TForm1.Button8Click(Sender: TObject); 
var 
  bmp: TBitmap; 
begin 
  bmp := TBitmap.Create; 
  bmp.LoadFromFile('d:\bilder\vogel.bmp'); 
  ChangeNearest2(bmp, $EFFFFF, clred); 
  canvas.draw(0, 0, bmp); 
  bmp.Free; 
end; 
//----------------------------------------------------------- 

// Methode 5: Eigentlich für Non-Palette-Bitmaps.
//            Paletten-Bitmaps werden auch unterstützt; sie werden
//            einfach umgewandelt. So gesehen gilt diese Methode
//            für alle Bitmaps.
function ChangeColor2(bmp: TBitmap; oldc, newc: TColor): boolean; var n: array[0..2] of Byte; r, g, b: byte; x, y, z, b3: integer; p: PBytearray; begin result := false; newc := colortorgb(newc); oldc := colortorgb(oldc); n[2] := getrvalue(newc); n[1] := getgvalue(newc); n[0] := getbvalue(newc); r := getrvalue(oldc); g := getgvalue(oldc); b := getbvalue(oldc); bmp.pixelformat := pf24bit; b3 := bmp.width * 3 - 1; for y := 0 to bmp.height - 1 do begin p := bmp.scanline[y]; x := 0; while x < b3 do begin if (p[x] = b) and (p[x + 1] = g) and (p[x + 2] = r) then begin for z := 0 to 2 do p[x + z] := n[z]; result := true; end; inc(x, 3); end; end; end; // Beispielaufruf procedure TForm1.Button9Click(Sender: TObject); var bmp: TBitmap; begin bmp := TBitmap.Create; bmp.LoadFromFile('d:\bilder\vogel.bmp'); if not ChangeColor2(bmp, bmp.canvas.pixels[0, bmp.height - 1], clred) then showmessage('Fehler') else canvas.draw(0, 0, bmp); bmp.Free; end;


Zugriffe seit 6.9.2001 auf Delphi-Ecke