AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Bitmap mit Milchglas-Effekt versehen?
Thema durchsuchen
Ansicht
Themen-Optionen

Bitmap mit Milchglas-Effekt versehen?

Ein Thema von Wormid · begonnen am 9. Okt 2003 · letzter Beitrag vom 10. Nov 2005
Antwort Antwort
Benutzerbild von Wormid
Wormid

Registriert seit: 26. Aug 2003
Ort: Steinfurt
292 Beiträge
 
Delphi XE2 Professional
 
#1

Bitmap mit Milchglas-Effekt versehen?

  Alt 9. Okt 2003, 21:38
Moin,

ich versuche gerade mir eine Funktion zu erstellen, die mir einen Ausschnitt eines Bitmaps quasi mit einer Milchglasscheibe überdeckt. Also im Grunde möchte ich einfach eine Weiße Fläche halbtransparent auf ein Bitmap legen. Nur so recht komme ich da nicht weiter.

Das habe ich bisher:

Delphi-Quellcode:
function DrawFrostedGlass(const Bitmap: TBitmap; GlassRect: TRect; Milk: TColor): TBitmap;
var x, y: Integer;
    P: PByteArray;
begin
  Result := TBitmap.Create;
  Result := Bitmap;

  // Den weissen Rahmen malen
  with Result.Canvas do begin
    Pen.Color := Milk;
    Brush.Style := bsClear;
    Rectangle(GlassRect);
  end;

  // Zeilen einzeln auslesen und Pixel einzeln verwursten...
  for y := GlassRect.Top + 1 to GlassRect.Bottom - 1 do
  begin
    P := Result.ScanLine[y];
    for x := GlassRect.Left + 1 to GlassRect.Right - 1 do
    begin
      // Tja, was nun?
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Bitmap: TBitmap;
begin
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromFile('splash_3.bmp');

  Image1.Picture.Bitmap := DrawFrostedGlass(Bitmap, Rect(16, 16, 301, 189), clWhite);

  Bitmap.Free;
end;
Im Screenshot kann man im linken Bitmap sehen, wie das Ergebnis aussieht. Im Bild rechts kann man sehen, wie das ganze mal aussehen soll (das ist mit nem Grafikproggie gemacht). Das Bild links ist im Urzustand auch ohne den weißen Rahmen, den will ich auch mitzeichnen...

Ich hoffe, jemand hat ne coole Idee, wie das so gehen kann!

Gruß

Wormid
Miniaturansicht angehängter Grafiken
milchglas.jpg  
Debuggers don't remove Bugs, they only show them in Slow-Motion.
  Mit Zitat antworten Zitat
Benutzerbild von Wormid
Wormid

Registriert seit: 26. Aug 2003
Ort: Steinfurt
292 Beiträge
 
Delphi XE2 Professional
 
#2

Re: Bitmap mit Milchglas-Effekt versehen?

  Alt 9. Okt 2003, 23:57
Pöh, wenn man hier nicht alles selber macht...

Die "heavy inspiration" habe ich mir hier geholt...

Delphi-Quellcode:
// Alphablending... Heavily inspired by janjan & DerKrasseHans @ DP(rulez)
// Source => Farbe des Quellpunktes
// Back => Farbe des Hintergrundes
// Alpha => Transparentheitsgrad in Werten zwischen 0..255
function CalcBlendingColor(const Source, Back: TColor; Alpha: Byte): TColor;
var r, g, b: Byte;
begin
  r := ColorToRGB(Back) and $0000FF;
  g := (ColorToRGB(Back) and $00FF00) shr 8;
  b := (ColorToRGB(Back) and $FF0000) shr 16;
  Result := TColor((r + ((((ColorToRGB(Source) and $0000FF) ) - r) * Alpha) div 255) +
                  ((g + ((((ColorToRGB(Source) and $00FF00) shr 8) - g) * Alpha) div 255) shl 8) +
                  ((b + ((((ColorToRGB(Source) and $FF0000) shr 16) - b) * Alpha) div 255) shl 16));
end;

// "Milchglasscheibe" mit einem 1-Pixel-Rahmen auf ein Bitmap zeichnen...
procedure DrawFrostedGlass(var Bitmap: TBitmap; const GlassRect: TRect; Milk: TColor = clWhite; Alpha: Byte = 128);
var x, y: Integer;
begin
  // Den Rahmen malen
  with Bitmap.Canvas do begin
    Pen.Color := Milk;
    Brush.Style := bsClear;
    Rectangle(GlassRect);
  end;
  // Zeilen einzeln auslesen und Pixel einzeln verwursten...
  for y := GlassRect.Top + 1 to GlassRect.Bottom - 1 do
    for x := GlassRect.Left + 1 to GlassRect.Right - 1 do
      Bitmap.Canvas.Pixels[x, y] := CalcBlendingColor(Bitmap.Canvas.Pixels[x, y], Milk, Alpha);
end;

procedure TForm1.Button1Click(Sender: TObject);
var Bitmap: TBitmap;
begin
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromFile('splash_3.bmp');

  DrawFrostedGlass(Bitmap, Rect(16, 16, 301, 189), clWhite, 175);
  Image1.Picture.Bitmap := Bitmap;

  Bitmap.Free;
end;
Funzen tut das ganze jetzt zwar... aber die Routine scheint sehr langsam zu sein. Hat jemand ne Idee, wie das vielleicht besser geht? Die Nummer mit "Scanline" habe ich nicht hinbekommen, da kam immer nur Farbensalat bei rum...


Gruß

Wormid
Debuggers don't remove Bugs, they only show them in Slow-Motion.
  Mit Zitat antworten Zitat
Benutzerbild von Sanchez
Sanchez

Registriert seit: 24. Apr 2003
Ort: Neumarkt Stmk
892 Beiträge
 
Delphi XE6 Enterprise
 
#3

Re: Bitmap mit Milchglas-Effekt versehen?

  Alt 10. Okt 2003, 06:42
hallo,
der Zugriff auf die Pixels ist sehr langsam, am Besten du löst das mit Scanlines

grüße, daniel

[EDIT]Sorry, hab grad erst gesehen, dass du die Scanlines schon probiert hast
Hast du auch dran gedacht das Pixelformat festzulegen, z.B:
  MyBitmap.PixelFormat:= pf24Bit;
Daniel
Testen ist feige!
  Mit Zitat antworten Zitat
Benutzerbild von Wormid
Wormid

Registriert seit: 26. Aug 2003
Ort: Steinfurt
292 Beiträge
 
Delphi XE2 Professional
 
#4

Re: Bitmap mit Milchglas-Effekt versehen?

  Alt 10. Okt 2003, 09:35
Tja... die Sache mit den Pixelformaten war mir irgendwie noch neu... Thx für den Tip.

Raus kam dabei jetzt folgendes:

Delphi-Quellcode:
// Einen TColor-Wert in die einzelnen RGB-Anteile umrechnen
procedure SplitColorToRGB(const Color: TColor; var r, g, b: Byte);
begin
  r := ColorToRGB(Color) and $0000FF;
  g := (ColorToRGB(Color) and $00FF00) shr 8;
  b := (ColorToRGB(Color) and $FF0000) shr 16;
end;

// Einzelne RGB-Anteile in einen TColor-Wert umrechnen
function RGBToColor(const r, g, b: Byte): TColor;
begin
  Result := TColor(r + (g shl 8) + (b shl 16));
end;

// Alphablending...
function CalcBlending(const Source, Back, Alpha: Byte): Byte;
begin
  Result := Back + ((Source - Back) * Alpha div 255);
end;

// "Milchglasscheibe" mit einem 1-Pixel-Rahmen auf ein Bitmap zeichnen...
procedure DrawFrostedGlass(var Bitmap: TBitmap; GlassRect: TRect; const Milk: TColor = clWhite; Alpha: Byte = 128);
var r, g, b: Byte;
    x, y: Integer;
    P: PByteArray;
begin
  // Den Rahmen malen
  with Bitmap.Canvas, Bitmap.Canvas.Pen do begin
    Color := Milk;
    Style := psSolid;
    Width := 1;
    Brush.Style := bsClear;
    Rectangle(GlassRect);
  end;

  // Vorbereitungen für das AlphaBlending
  Bitmap.PixelFormat := pf24Bit;
  GlassRect.Left := (GlassRect.Left * 3) + 3;
  GlassRect.Right := (GlassRect.Right * 3) - 3;
  SplitColorToRGB(Milk, r, g, b);

  // Zeilen einzeln auslesen und Pixel einzeln verwursten...
  for y := GlassRect.Top + 1 to GlassRect.Bottom - 1 do
  begin
    P := Bitmap.ScanLine[y];
    x := GlassRect.Left;
    repeat
      P[x+0] := CalcBlending(P[x+0], r, Alpha);
      P[x+1] := CalcBlending(P[x+1], g, Alpha);
      P[x+2] := CalcBlending(P[x+2], b, Alpha);
      Inc(x, 3);
    until x >= GlassRect.Right;
  end;
end;
Die Routine ist jetzt zwar etwas länger (und das repeat ... until passt mir auch nicht), aber sie ist spürbar schneller, als die erste Variante!

Gruß

Wormid
Debuggers don't remove Bugs, they only show them in Slow-Motion.
  Mit Zitat antworten Zitat
Benutzerbild von Tonic1024
Tonic1024

Registriert seit: 10. Sep 2003
Ort: Cuxhaven
559 Beiträge
 
RAD-Studio 2009 Ent
 
#5

Re: Bitmap mit Milchglas-Effekt versehen?

  Alt 10. Okt 2003, 12:22
Moin...

Ich mix mich hier mal rein, obwohl ich nichts sinnvolles beizusteuern habe... Aber dieser Milchlas-Effekt interessiert mich jetzt grade mal...

Ich habe mit Pixel und Bildbearbeitung praktisch keinerlei Erfahrung, habe aber eine (privates) Projekt in Vorbereitung, wo ich das gut gebrauchen kann...

Gleich mal vorweg... Ich weiss schon was ein RGB-Wert ist, was der macht und wie man damit umgeht. Zahlen sind mir durchaus Sympathisch und auch "Binär-Tricksereien" mag ich sehr...

Ich habe mir den Source mal genauer angeschaut... Habe hier leider keine Möglichkeit zu testen (wenn mein chef das sieht...) und zu Haus (noch) kein Delphi. Spare lieber auf ein Original statt Esel-Ware.

Was ist/macht alphablending im allgemeinen? Wie es geht steht ja oben...

Wormit schrieb, es dauerte sehr lange. Wie lange ist Lange? Gar mehrere Sekunden oder doch weniger? Und bei welchem Umfang (Bildgröße)?

bis denne...
Der frühe Vogel fängt den Wurm, richtig.
Aber wird nicht auch der frühe Wurm vom Vogel gefressen?
  Mit Zitat antworten Zitat
Benutzerbild von Sanchez
Sanchez

Registriert seit: 24. Apr 2003
Ort: Neumarkt Stmk
892 Beiträge
 
Delphi XE6 Enterprise
 
#6

Re: Bitmap mit Milchglas-Effekt versehen?

  Alt 10. Okt 2003, 12:27
Alphablending bringt Transparenz bzw. Überblendeffekte.
Sehr langsam ist allerdings nur die erste Version mit den pixels, mit den Scanlines gehts ungleich schneller.
Daniel
Testen ist feige!
  Mit Zitat antworten Zitat
Benutzerbild von Wormid
Wormid

Registriert seit: 26. Aug 2003
Ort: Steinfurt
292 Beiträge
 
Delphi XE2 Professional
 
#7

Re: Bitmap mit Milchglas-Effekt versehen?

  Alt 10. Okt 2003, 13:25
Zitat von Tonic1024:
Wormit schrieb, es dauerte sehr lange. Wie lange ist Lange? Gar mehrere Sekunden oder doch weniger? Und bei welchem Umfang (Bildgröße)?

bis denne...
Die Bilder mit denen ich jetzt getestet habe waren 320 * 240 Pixel groß... als Bitmap so um die 230kb. Bei der ersten Version war eine kurze Verzögerung beim Aufbau des Bildes zu spüren (~ 1 Sekunde auf nem AMD XP2600), bei der zweiten Version erscheint das Bild scheinbar sofort.

Gruß

Wormid
Debuggers don't remove Bugs, they only show them in Slow-Motion.
  Mit Zitat antworten Zitat
Gandalfus

Registriert seit: 19. Apr 2003
407 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Bitmap mit Milchglas-Effekt versehen?

  Alt 10. Okt 2003, 13:31
http://www.tutorials.delphi-source.d.../file007.shtml
und
http://www.sokratez.de/alphablending.htm
  Mit Zitat antworten Zitat
static_cast

Registriert seit: 19. Okt 2003
Ort: Peine
300 Beiträge
 
#9

Re: Bitmap mit Milchglas-Effekt versehen?

  Alt 10. Nov 2005, 12:32
Hi Wormid,

ich hab einen kleinen Fehler gefunden, in deinem Code steht:

Delphi-Quellcode:
P[x+0] := CalcBlending(P[x+0], r, Alpha);
P[x+1] := CalcBlending(P[x+1], g, Alpha);
P[x+2] := CalcBlending(P[x+2], b, Alpha);
aber es müsste so sein:

Delphi-Quellcode:
P[x+0] := CalcBlending(P[x+0], b, Alpha);
P[x+1] := CalcBlending(P[x+1], g, Alpha);
P[x+2] := CalcBlending(P[x+2], r, Alpha);
da sonst alle Farben invertiert sind, bei weiß fällt es ja nicht auf aber als ich es mit skyblue versucht habe wunderte ich mich warum er immer so ein k* braun bei rauskommt


Gruß,
Daniel
Daniel M.
"The WM_NULL message performs no operation. An application sends the WM_NULL message if it wants to post a message that the recipient window will ignore."
  Mit Zitat antworten Zitat
Antwort Antwort


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 09:48 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