![]() |
Bitmap-Ausschnitt einfärben
Ich möchte einen Teil eines Bitmaps/Canvas einfärben.
Es soll ein kleiner Effekt erkennbar sein (etwas dunkler oder etwas blauer z.B.). Der Effekt soll in zwei Variationen anwendbar sein (mehr oder weniger abgedunkelt oder etwas anders eingefärbt). Möglichst will ich mit dem normalen Bitmap arbeiten. Versuche mit CopyRect und StretchBlt durchblicke ich nicht. Die Zielfläche wird meist weiß oder schwarz und ich habe kein Grundverständnis, wo ich drehen muss. Es soll ein kleiner und einfacher Effekt sein. Ich will nur einen kleinen Unterschied zum Originalausschnitt erkennen (so eine Art Mouseover-Effekt). Hat jemand einen Tipp? |
AW: Bitmap-Ausschnitt einfärben
Ich denke du kommst um ScanLine nicht herum.
Wie bekommt man nun die Farbe etwas heller oder dunkler? Ich bin an der Frage mal fast verzweifelt, die Lösung (Trick) war letztendlich simpel. Nicht versuchen die Farbe heller oder dunkler zu berechnen, sondern einfach prozentual mit weiß (heller) oder schwarz (dunkler) mischen. Das Ergebnis ist heller oder dunkler. |
AW: Bitmap-Ausschnitt einfärben
Zitat:
![]() |
AW: Bitmap-Ausschnitt einfärben
Erstens: Selbst ist der Mann
Zweitens: Kennt meine OH von D7 nicht. Und was der Bauer nicht kennt... |
AW: Bitmap-Ausschnitt einfärben
|
AW: Bitmap-Ausschnitt einfärben
Mach das einfach mit Scanline... es ist nicht so kompliziert wie es sich vielleicht anhört.
Ich habs grad einfach mal aus dem Kopf runtergeschrieben, weil es glaub ich länger dauern würde, es mit Worten zu erklären, und dann immer noch unklarer wäre:
Delphi-Quellcode:
function Clamp(Value: Integer; Min, Max: Integer); inline;
begin Result := Value; if Result < Min then Result := Min; if Result > Max then Result := Max; end; procedure AdjustLuminance(Bmp: TBitmap; Offset: SmallInt) Bmp: TBitmap; Pixel: PRGBQuad; x,y: integer; begin Bmp.PixelFormat := pf32Bit; for y := 0 to Bmp.Height - 1 do begin // Pointer auf 1. Pixel in der Zeile holen Pixel := Bmp.Scanline[y]; for x := 0 to Bmp.Width - 1 do begin Pixel^.R := Clamp(Pixel^.R + Offset, 0, 255); Pixel^.G := Clamp(Pixel^.G + Offset, 0, 255; Pixel^.B := Clamp(Pixel^.B + Offset, 0, 255); // ein Pixel nach rechts gehen inc(Pixel); end; end; end;
Delphi-Quellcode:
Für PRGBQuad musst du irgendeine Unit einbinden, ich hab es grad nicht im Kopf, welche. Oder du deklarierst dir den Record einfach selbst:
AdjustLuminance(Bmp, 50); // Aufhellen
AdjustLuminance(Bmp, -50); // Abdunkeln
Delphi-Quellcode:
PS: Kann sein, dass Luminance hier formal gesehen der richtige Begriff ist. Aber für einen Hover-Effekt reicht es allemal, und wenn nicht, kann man die Berechnung in der Schleife ja einfach austauschen.
type
PRGBQuad = ^TRGBQuad; TRGBQuad = packed record B, G, R, A: Byte; end; |
AW: Bitmap-Ausschnitt einfärben
Liste der Anhänge anzeigen (Anzahl: 1)
Ihr seid Helden und eine Heldin! :-)
Anbei mal meine Versuche und zwei Exen. Ich werde es erst mal bei DrawTransparentBitmap lassen. Das ist natürlich nicht performant, aber im Moment stört das nicht. Mit der Lumi-Variante ist der Text nicht mehr lesbar bzw. bei positiven Werten werden weiße Flächen schwarz. Da ich kein Verständnis für Farbänderungen habe lasse ich es erst mal dabei. Für meinen kleinen Test reicht es erst mal.
Delphi-Quellcode:
...
unit Winapi.Windows; ... function Clamp(Value: Integer; Min, Max: Integer): Byte; inline; begin Result := Value; if Result < Min then Result := Min; if Result > Max then Result := Max; end; procedure AdjustLuminance(Bmp: TBitmap; Offset: SmallInt); var // Bmp: TBitmap; Pixel: PRGBQuad; X, Y: Integer; begin Bmp.PixelFormat := pf32Bit; for Y := ClientRect.Top to ClientRect.Bottom do begin // Pointer auf 1. Pixel in der Zeile holen Pixel := Bmp.Scanline[Y]; System.Inc(Pixel, ClientRect.Left); for X := ClientRect.Left to ClientRect.Right do begin Pixel^.rgbRed := Clamp(Pixel^.rgbRed + Offset, 0, 255); Pixel^.rgbGreen := Clamp(Pixel^.rgbGreen + Offset, 0, 255); Pixel^.rgbBlue := Clamp(Pixel^.rgbBlue + Offset, 0, 255); // ein Pixel nach rechts gehen System.Inc(Pixel); end; end; end; procedure UnderMouseEffect; var tmpBitmap: TBitmap; begin tmpBitmap := TBitmap.Create; tmpBitmap.Width := ClientRect.Width; tmpBitmap.Height := ClientRect.Height; tmpBitmap.Canvas.Brush.Style := bsDiagCross; tmpBitmap.Canvas.Brush.Color := clWhite; tmpBitmap.Canvas.FillRect(TRect.Create(0, 0, tmpBitmap.Width, tmpBitmap.Height)); // tmpBitmap.SaveToFile('xxx.bmp'); DrawTransparentBitmap(tmpBitmap, aBitmap.Canvas, ClientRect, $07); // aBitmap.Canvas.Brush.Color := clYellow; // aBitmap.Canvas.FillRect(aRect); // SetStretchBltMode(aBitmap.Canvas.Handle, COLORONCOLOR); // StretchBlt(aBitmap.Canvas.Handle, ClientRect.Left, ClientRect.Top, // ClientRect.Width, ClientRect.Height, tmpBitmap.Canvas.Handle, 0, 0, // tmpBitmap.Width, tmpBitmap.Height, SRCCOPY); // aBitmap.Canvas.CopyMode := cmWhiteness; // aBitmap.Canvas.CopyRect(ClientRect, tmpBitmap.Canvas, // tmpBitmap.Canvas.ClipRect); tmpBitmap.Free; end; procedure MouseDownEffect; var tmpBitmap: TBitmap; begin tmpBitmap := TBitmap.Create; tmpBitmap.Width := ClientRect.Width; tmpBitmap.Height := ClientRect.Height; tmpBitmap.Canvas.Brush.Style := bsDiagCross; tmpBitmap.Canvas.Brush.Color := clWhite; tmpBitmap.Canvas.FillRect(TRect.Create(0, 0, tmpBitmap.Width, tmpBitmap.Height)); // tmpBitmap.SaveToFile('xxx.bmp'); DrawTransparentBitmap(tmpBitmap, aBitmap.Canvas, ClientRect, $10); // aBitmap.Canvas.Brush.Color := clYellow; // aBitmap.Canvas.FillRect(aRect); // SetStretchBltMode(aBitmap.Canvas.Handle, COLORONCOLOR); // StretchBlt(aBitmap.Canvas.Handle, ClientRect.Left, ClientRect.Top, // ClientRect.Width, ClientRect.Height, tmpBitmap.Canvas.Handle, 0, 0, // tmpBitmap.Width, tmpBitmap.Height, SRCCOPY); // aBitmap.Canvas.CopyMode := cmWhiteness; // aBitmap.Canvas.CopyRect(ClientRect, tmpBitmap.Canvas, // tmpBitmap.Canvas.ClipRect); tmpBitmap.Free; end; procedure UnderMouseEffectLumi; begin AdjustLuminance(aBitmap, -2); // Abdunkeln end; procedure MouseDownEffectLumi; begin AdjustLuminance(aBitmap, -5); // Abdunkeln end; |
AW: Bitmap-Ausschnitt einfärben
Liste der Anhänge anzeigen (Anzahl: 1)
Vielleicht ist auch Alphablending für dich interessant, z.B. hier:
![]() Damit könntest du sowas erzielen: Anhang 40760 |
AW: Bitmap-Ausschnitt einfärben
Komisch, versuch es mal so:
Delphi-Quellcode:
Pixel^.rgbRed := Clamp(integer(Pixel^.rgbRed) + Offset, 0, 255);
Pixel^.rgbGreen := Clamp(integer(Pixel^.rgbGreen) + Offset, 0, 255); Pixel^.rgbBlue := Clamp(integer(Pixel^.rgbBlue) + Offset, 0, 255); |
AW: Bitmap-Ausschnitt einfärben
Liste der Anhänge anzeigen (Anzahl: 1)
Ja, AlphaBlend passt gut. :thumb:
Für den Fall, dass jemand in dem Bereich Infos sucht, hier der aktuelle Stand:
Delphi-Quellcode:
@Namenloser: Brachte keine Besserung (für mich jetzt auch nicht dringend).
procedure UnderMouseEffectDrawTransp;
var tmpBitmap: TBitmap; begin tmpBitmap := TBitmap.Create; tmpBitmap.Width := ClientRect.Width; tmpBitmap.Height := ClientRect.Height; tmpBitmap.Canvas.Brush.Style := bsDiagCross; tmpBitmap.Canvas.Brush.Color := clWhite; tmpBitmap.Canvas.FillRect(TRect.Create(0, 0, tmpBitmap.Width, tmpBitmap.Height)); // tmpBitmap.SaveToFile('xxx.bmp'); DrawTransparentBitmap(tmpBitmap, aBitmap.Canvas, ClientRect, $07); // aBitmap.Canvas.Brush.Color := clYellow; // aBitmap.Canvas.FillRect(aRect); // SetStretchBltMode(aBitmap.Canvas.Handle, COLORONCOLOR); // StretchBlt(aBitmap.Canvas.Handle, ClientRect.Left, ClientRect.Top, // ClientRect.Width, ClientRect.Height, tmpBitmap.Canvas.Handle, 0, 0, // tmpBitmap.Width, tmpBitmap.Height, SRCCOPY); // aBitmap.Canvas.CopyMode := cmWhiteness; // aBitmap.Canvas.CopyRect(ClientRect, tmpBitmap.Canvas, // tmpBitmap.Canvas.ClipRect); tmpBitmap.Free; end; procedure MouseDownEffectDrawTransp; var tmpBitmap: TBitmap; begin tmpBitmap := TBitmap.Create; tmpBitmap.Width := ClientRect.Width; tmpBitmap.Height := ClientRect.Height; tmpBitmap.Canvas.Brush.Style := bsDiagCross; tmpBitmap.Canvas.Brush.Color := clWhite; tmpBitmap.Canvas.FillRect(TRect.Create(0, 0, tmpBitmap.Width, tmpBitmap.Height)); // tmpBitmap.SaveToFile('xxx.bmp'); DrawTransparentBitmap(tmpBitmap, aBitmap.Canvas, ClientRect, $10); // aBitmap.Canvas.Brush.Color := clYellow; // aBitmap.Canvas.FillRect(aRect); // SetStretchBltMode(aBitmap.Canvas.Handle, COLORONCOLOR); // StretchBlt(aBitmap.Canvas.Handle, ClientRect.Left, ClientRect.Top, // ClientRect.Width, ClientRect.Height, tmpBitmap.Canvas.Handle, 0, 0, // tmpBitmap.Width, tmpBitmap.Height, SRCCOPY); // aBitmap.Canvas.CopyMode := cmWhiteness; // aBitmap.Canvas.CopyRect(ClientRect, tmpBitmap.Canvas, // tmpBitmap.Canvas.ClipRect); tmpBitmap.Free; end; function Clamp(Value: Integer; Min, Max: Integer): Byte; inline; begin Result := Value; if Result < Min then Result := Min; if Result > Max then Result := Max; end; procedure AdjustLuminance(Bmp: TBitmap; Offset: SmallInt); var // Bmp: TBitmap; Pixel: PRGBQuad; X, Y: Integer; begin Bmp.PixelFormat := pf32Bit; for Y := ClientRect.Top to ClientRect.Bottom do begin // Pointer auf 1. Pixel in der Zeile holen Pixel := Bmp.Scanline[Y]; System.Inc(Pixel, ClientRect.Left); for X := ClientRect.Left to ClientRect.Right do begin Pixel^.rgbRed := Clamp(Integer(Pixel^.rgbRed) + Offset, 0, 255); Pixel^.rgbGreen := Clamp(Integer(Pixel^.rgbGreen) + Offset, 0, 255); Pixel^.rgbBlue := Clamp(Integer(Pixel^.rgbBlue) + Offset, 0, 255); // ein Pixel nach rechts gehen System.Inc(Pixel); end; end; end; procedure UnderMouseEffectLumi; begin AdjustLuminance(aBitmap, -2); // Abdunkeln end; procedure MouseDownEffectLumi; begin AdjustLuminance(aBitmap, -5); // Abdunkeln end; procedure UnderMouseEffectAlpha; var tmpBitmap: TBitmap; BlendFunc: TBlendFunction; begin tmpBitmap := TBitmap.Create; tmpBitmap.Width := ClientRect.Width; tmpBitmap.Height := ClientRect.Height; tmpBitmap.Canvas.Brush.Color := clHighlight; tmpBitmap.Canvas.FillRect(Rect(0, 0, tmpBitmap.Width, tmpBitmap.Height)); // Blend a foreground image over the top - constant alpha, not per-pixel BlendFunc.BlendOp := AC_SRC_OVER; BlendFunc.BlendFlags := 0; BlendFunc.SourceConstantAlpha := 5; BlendFunc.AlphaFormat := 0; AlphaBlend(aBitmap.Canvas.Handle, ClientRect.Left, ClientRect.Top, tmpBitmap.Width, tmpBitmap.Height, tmpBitmap.Canvas.Handle, 0, 0, tmpBitmap.Width, tmpBitmap.Height, BlendFunc); tmpBitmap.Free; end; procedure MouseDownEffectAlpha; var tmpBitmap: TBitmap; BlendFunc: TBlendFunction; begin tmpBitmap := TBitmap.Create; tmpBitmap.Width := ClientRect.Width; tmpBitmap.Height := ClientRect.Height; tmpBitmap.Canvas.Brush.Color := clHighlight; tmpBitmap.Canvas.FillRect(Rect(0, 0, tmpBitmap.Width, tmpBitmap.Height)); // Blend a foreground image over the top - constant alpha, not per-pixel BlendFunc.BlendOp := AC_SRC_OVER; BlendFunc.BlendFlags := 0; BlendFunc.SourceConstantAlpha := 20; BlendFunc.AlphaFormat := 0; AlphaBlend(aBitmap.Canvas.Handle, ClientRect.Left, ClientRect.Top, tmpBitmap.Width, tmpBitmap.Height, tmpBitmap.Canvas.Handle, 0, 0, tmpBitmap.Width, tmpBitmap.Height, BlendFunc); tmpBitmap.Free; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz