// 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;
|