AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Bitmap-Ausschnitt einfärben

Ein Thema von stahli · begonnen am 21. Feb 2014 · letzter Beitrag vom 21. Feb 2014
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#1

Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 07:26
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?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#2

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 08:03
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.
  Mit Zitat antworten Zitat
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 08:20
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.
Oder man verwendet die Funktion ColorAdjustLuma.
Hinter dir gehts abwärts und vor dir steil bergauf ! (Wolfgang Ambros)

Geändert von baumina (21. Feb 2014 um 09:23 Uhr)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#4

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 08:30
Erstens: Selbst ist der Mann

Zweitens: Kennt meine OH von D7 nicht. Und was der Bauer nicht kennt...
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 08:59
ColorAdjustLuma
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 09:46
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:
AdjustLuminance(Bmp, 50); // Aufhellen
AdjustLuminance(Bmp, -50); // Abdunkeln
Für PRGBQuad musst du irgendeine Unit einbinden, ich hab es grad nicht im Kopf, welche. Oder du deklarierst dir den Record einfach selbst:
Delphi-Quellcode:
type
  PRGBQuad = ^TRGBQuad;
  TRGBQuad = packed record
    B, G, R, A: Byte;
  end;
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.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 10:26
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;
Angehängte Dateien
Dateityp: zip Effect.zip (1,74 MB, 8x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (21. Feb 2014 um 10:43 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.735 Beiträge
 
Delphi 2007 Professional
 
#8

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 10:47
Vielleicht ist auch Alphablending für dich interessant, z.B. hier: http://itinerantdeveloper.blogspot.d...-gdi-part.html.
Damit könntest du sowas erzielen:
constant-alpha.png
Uli Gerhardt
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#9

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 11:12
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);
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Bitmap-Ausschnitt einfärben

  Alt 21. Feb 2014, 11:37
Ja, AlphaBlend passt gut.

Für den Fall, dass jemand in dem Bereich Infos sucht, hier der aktuelle Stand:

Delphi-Quellcode:
  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;
@Namenloser: Brachte keine Besserung (für mich jetzt auch nicht dringend).
Angehängte Dateien
Dateityp: zip Effect.zip (2,61 MB, 19x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz