![]() |
halbtransparenten text auf TImage?
Hi ;)
Ich plage mich seit gestern damit rum, einen text mit einer bestimmten Deckkraft auf ein TImage zu zeichnen. Bisher hab ich TextOut, nur da gibts keine transparenz. Nunja...mir wurden 2 Möglichkeiten dargestellt: - Pixelmanipulation - AlphaBlending Wobei eins dem anderem sehr ähnlich kommt. Ich habe mal als "Grundgerüst" das zusammengebastelt:
Delphi-Quellcode:
Nunja.
function trans_text(const src, dest: TBitmap; opacity: real): Boolean;
var w,h: integer; color, color2: Longint; r,g,b: byte; r2,g2,b2: byte; rr,gg,bb: byte; begin for h:=0 to src.Height do begin for w:=0 to src.Width do begin color := ColorToRGB(src.Canvas.pixels[w,h]); r := GetRValue(color); g := GetGValue(color); b := GetBValue(color); color2 := ColorToRGB(dest.Canvas.pixels[w,h]); r2 := GetRValue(color2); g2 := GetGValue(color2); b2 := GetBValue(color2); rr := (r*r2) / 255; gg := (g*g2) / 255; bb := (b*b2) / 255; dest.Canvas.pixels[w,h] := RGB(rr,gg,bb); end; end; end; 2 Probleme sind offensichtlich: 1. Die richtige Formel zur Manipulation 2. Nur Pixel manipulieren, die nich transparent sind Übrigens: src ist ein TImage, auf dem ich mit TextOut schreib, dest ein TImage, wo das ganze dann drauf soll (schon ein anderes bild vorhanden) und nein, ich meine nicht den weissen kasten, den man mit bsClear wegbekommt. ich meine, dass die schrift eben transparent werden soll, mit einstellbarer deckkraft (opacity) Kann mir jmd helfen? :? |
Re: halbtransparenten text auf TImage?
Erstmal Herzlich Willkommen in der DP!
Soweit ich weiss, gibt es nur 256 Levels der Transparenz, also ist Opacity: Real eher ein Byte. Übrigens ist dein Code falsch: Die Transaprenz errechnet sich anders. Die Grundlagen sind recht simpel: Du nimmst dir das src-Pixel, teilst den Farbwert durch 255 (da kommst du um Real nicht herum) und multiplizierst es dann mit Opacity. Dann machst du das selbe mit den Dest-Pixel, nur multiplizierst du mit (255-Opacity). Am Ende werden beide Werte (jeweils R, G und B) addiert, und du hast ein Transparentes Pixel. |
Re: halbtransparenten text auf TImage?
Erstmal Danke ;)
Ja, war nur eben zusammengeschsutert..und wie gesagt: Dass die Formel falsch ist, war mir klar ;) Ich werde jetzt mal schauen was ich hinbekomm :) air |
Re: halbtransparenten text auf TImage?
Allerdings solltest du bei dem obigen Vorschlag beachten, dass du nicht weisst, welches Pixel bereits transparent war und nachher nicht weisst, welches Pixel welchen Transparenzwert besitzt.
|
Re: halbtransparenten text auf TImage?
Zitat:
aber wie frage ich ab, ob der aktuelle pixel bereits transparent ist? hab es nun so:
Delphi-Quellcode:
air
function text_opacity(const src,dest: TBitmap; opacity: byte): Boolean;
[...] function TForm1.text_opacity(const src,dest: TBitmap; opacity: byte): Boolean; var w,h: integer; col, col2: Longint; r1, g1, b1: byte; r2, g2, b2: byte; rr, gg, bb: byte; begin for h:=0 to src.Height do begin for w:=0 to src.Width do begin // Src: col := ColorToRGB(src.Canvas.Pixels[w,h]); // Pixelfarbe // Nun R G und B Wert holen: r1 := GetRValue(col); g1 := GetGValue(col); b1 := GetBValue(col); // Dest: col2 := ColorToRGB(dest.Canvas.Pixels[w,h]); // Pixelfarbe // Nun R G und B Wert holen: r2 := GetRValue(col2); g2 := GetGValue(col2); b2 := GetBValue(col2); // Neue RGB Werte errechnen rr := ((r/255)*opacity) + (r2*(255-opacity)); gg := ((g/255)*opacity) + (g2*(255-opacity)); bb := ((b/255)*opacity) + (b2*(255-opacity)); // Pixel neu zeichnen dest.Canvas.Pixels[w,h] := RGB(rr,gg,bb); end; end; end; P.S. Ne dumme Frage...ist mein Stil ordentlich? |
Re: halbtransparenten text auf TImage?
Der Stil ist in Ordnung, allerdings musst du die x2-Werte auch noch durch 255 Teilen (fehlt das in meiner Erklärung?).
Und: Der einzige Weg, die Transparenz eines Pixel abzufragen, ist der Alphakanal, also die letzten 8 Bit bei einer 32Bit-Bitmap. |
Re: halbtransparenten text auf TImage?
hm hups..überlesen ;)
OK....ich hab halt nur die 24er Bitmap...is ja klar. D.h. es gibt keinen Weg? Dann wäre der Rest ja auch umsonst *fg* Mir fällt nur eine Möglichkeit ein: Ich gebe beim Funktionsaufruf noch mit an, welche Farbe transparent sein soll. D.h. ich habe bei der src-bmp eine Hintergrundfarbe, die je nach textfarbe anders ist. Diese geb ich mit an. Dann frag ich bevor ich manipuliere ab, ob der Pixel die gelieferte Farbe hat. Wäre das eine Möglichkeit? air P.S. Aktuell:
Delphi-Quellcode:
function TForm1.text_opacity(const src,dest: TBitmap; opacity: byte): Boolean;
var w,h: integer; col, col2: Longint; r1, g1, b1: byte; r2, g2, b2: byte; rr, gg, bb: byte; begin for h:=0 to src.Height do begin for w:=0 to src.Width do begin // Src: col := ColorToRGB(src.Canvas.Pixels[w,h]); // Pixelfarbe // Nun R G und B Wert holen: r1 := GetRValue(col); g1 := GetGValue(col); b1 := GetBValue(col); // Dest: col2 := ColorToRGB(dest.Canvas.Pixels[w,h]); // Pixelfarbe // Nun R G und B Wert holen: r2 := GetRValue(col2); g2 := GetGValue(col2); b2 := GetBValue(col2); // Neue RGB Werte errechnen rr := ((r/255)*opacity) + ((r2/255)*(255-opacity)); gg := ((g/255)*opacity) + ((g2/255)*(255-opacity)); bb := ((b/255)*opacity) + ((b2/255)*(255-opacity)); // Pixel neu zeichnen dest.Canvas.Pixels[w,h] := RGB(rr,gg,bb); end; end; end; |
Re: halbtransparenten text auf TImage?
Du willst nur eine bestimmte Farbe transparent machen? Das geht ohne Probleme.
Ich sehe grade, in deinem Code ist noch ein Fehler: Der Operator / liefert Real-Ergebnisse zurück, du musst also bein den Pixelberechnungen den Fliesskommateil noch mit ![]() |
Re: halbtransparenten text auf TImage?
Nein.
Ich will ja einen schlichten Text auf ein Bild malen. Da ich im 24er Bitmap die Transparenz aber nicht abfragen kann, könnte ich doch in dem src-Bitmap als Hintergrundfarbe eine Farbe setzen, die ich beim Funktionsaufruf angebe. So kann ich anstatt die Transparenz abzufragen, die gegebene Farbe abfragen. Wenn der akt. Pixel dieser Farbe entspricht, bekommt der Pixel den Farbwert der Dest-Bitmap die diesem Pixel entspricht. Hoffe nun geklärt zu haben :) /edit: mit Trunc:
Delphi-Quellcode:
function TForm1.text_opacity(const src,dest: TBitmap; opacity: byte): Boolean;
var w,h: integer; col, col2: Longint; r1, g1, b1: byte; r2, g2, b2: byte; rr, gg, bb: byte; begin for h:=0 to src.Height do begin for w:=0 to src.Width do begin // Src: col := ColorToRGB(src.Canvas.Pixels[w,h]); // Pixelfarbe // Nun R G und B Wert holen: r1 := GetRValue(col); g1 := GetGValue(col); b1 := GetBValue(col); // Dest: col2 := ColorToRGB(dest.Canvas.Pixels[w,h]); // Pixelfarbe // Nun R G und B Wert holen: r2 := GetRValue(col2); g2 := GetGValue(col2); b2 := GetBValue(col2); // Neue RGB Werte errechnen rr := (Trunc(r/255)*opacity) + (Trunc(r2/255)*(255-opacity)); gg := (Trunc(g/255)*opacity) + (Trunc(g2/255)*(255-opacity)); bb := (Trunc(b/255)*opacity) + (Trunc(b2/255)*(255-opacity)); // Pixel neu zeichnen dest.Canvas.Pixels[w,h] := RGB(rr,gg,bb); end; end; end; |
Re: halbtransparenten text auf TImage?
Dann nützt dir der Opacity-Wert aber nichts mehr - weil du ja einfach nur die src-Pixel oder die Dest-Pixel kopierst, ohne Alpha-Blend.
Und: Die Funktion, die du suchst, gibt es schon. ![]() Ausserdem würde ich dir raten, erst am Ende der Transparenzrechnung zu runden, damit möglichst wenig Information verlorengeht. |
Re: halbtransparenten text auf TImage?
Zitat:
Ich will den Text selber Transparent haben...mehr nich *langsam verzweifelt* ;) Wenn ich den bereits transparenten Pixel mit dem Dest-Pixel "verrechne" kommt ja eine ungewollte Farbänderung zustande..oder? Um mein Vorhaben ganz kurz zu beschreiben: Eine Art Deckkraft-Funktion wie in Photoshop o.ä. Nur, dass man hier die Deckkraft nur 1x einstellen können muss und nicht dauernd ändern können muss /Edit: Könnte man nicht auch das Format der Bitmap temporär auf 32Bit stellen? /Edit2: Meintest du so?
Delphi-Quellcode:
rr := Trunc(((r/255)*opacity) + ((r2/255)*(255-opacity)));
gg := Trunc(((g/255)*opacity) + ((g2/255)*(255-opacity))); bb := Trunc(((b/255)*opacity) + ((b2/255)*(255-opacity))); |
Re: halbtransparenten text auf TImage?
Soll die Transparenz des TImage erhalten bleiben oder soll zwichen den Buchstaben die Transparenz (vollständige durchsichtigkeit) erhalten bleiben?
|
Re: halbtransparenten text auf TImage?
Ja, so meinte ich das. Ansonsten könnte Farbinformation verloregehen..
|
Re: halbtransparenten text auf TImage?
nochmal^^
ich will einfach nur einen text auf ein bild zeichnen. dieser text soll aber opacity haben, d.h. ich kann sagen, ob er nur zu 50% erscheinen soll...also halt halbtransparent. |
Re: halbtransparenten text auf TImage?
Geduld, Source ist fast fertig... (eigentlich total simpel)
|
Re: halbtransparenten text auf TImage?
Zitat:
Eig. wollt ichs selber machen...aber ich glaub, hier lern ich durch anschauen mehr :? |
Re: halbtransparenten text auf TImage?
Hier mein Meisterwerk, hoffe es ist einigermaßen verständlich.
Delphi-Quellcode:
Beispielaufruf (gibt 'Testtext' an Position X: 10 Y: 15 auf dem Bild aus)
function GetBlendColor(BaseColor: TColor; BlendColor: TColor; AlphaVal: Byte): TColor;
type TMyColor = record red: Byte; green: Byte; blue: Byte; end; var LF1, LF2: TMyColor; begin LF1.red := GetRValue(Basecolor); LF1.green := GetGValue(Basecolor); LF1.blue := GetBValue(Basecolor); LF2.red := (LF1.red * (255-AlphaVal) + GetRValue(Blendcolor) * AlphaVal) div 255; LF2.green := (LF1.green * (255-AlphaVal) + GetGValue(Blendcolor) * AlphaVal) div 255; LF2.blue := (LF1.blue * (255-AlphaVal) + GetBValue(Blendcolor) * AlphaVal) div 255; result := rgb(LF2.red, LF2.green, LF2.blue); end; procedure DrawTexttoBitmap1(ADest: TBitmap; AText: String; AFont: TFont; AlphaVal: Byte; APos: TPoint); var LBmp1: TBitmap; LBGColor, LColor1, LColor2: TColor; LWdhX, LWdhY: Integer; begin if AText <> '' then begin LBmp1 := TBitmap.Create; LBmp1.Canvas.Font.Assign(AFont); LBmp1.Width := LBmp1.Canvas.TextWidth(AText); LBmp1.Height := LBmp1.Canvas.TextHeight(AText); if AFont.Color = clWhite then LBGColor := clBlack else LBGColor := clWhite; LBmp1.Canvas.Brush.Color := LBGColor; LBmp1.Canvas.FillRect(Rect(0, 0, LBmp1.Width, LBmp1.Height)); LBmp1.Canvas.TextOut(0,0, AText); LWdhX := 0; while (LWdhX < ADest.Width - APos.X) and (LWdhX < LBmp1.Width) do begin LWdhY := 0; while (LWdhY < ADest.Height - APos.Y) and (LWdhY < LBmp1.Height) do begin LColor1 := LBmp1.Canvas.Pixels[LWdhX, LWdhY]; if LColor1 <> LBGColor then begin LColor2 := ADest.Canvas.Pixels[LWdhX + APos.X, LWdhY + APos.Y]; ADest.Canvas.Pixels[LWdhX + APos.X, LWdhY + APos.Y] := GetBlendColor(LColor2, LColor1, AlphaVal); end; inc(LWdhY); end; inc(LWdhX); end; LBmp1.Free; end; end;
Delphi-Quellcode:
Alphaval muss ein wert zwischen 0 (Text ist nicht sichtbar) und 255 (Text hat volle Deckkraft) sein
DrawTexttoBitmap1(Image1.Picture.Bitmap, 'Testtext', Font, 50, Point(10, 15));
|
Re: halbtransparenten text auf TImage?
Danke :-D
Bin die nächsten Minuten dann erstmal mit lesen und testen beschäftigt.. *fg* Edit: DANKÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ :mrgreen: Funktioniert einwandfrei! Genauso wie ichs wollte :) *auf Knie fall und anbet* So...nun muss ich mir den Code aber dringstens auch ansehen :) |
Re: halbtransparenten text auf TImage?
Falls den Quelltext jemand nicht versteht - fogendes wird gemacht.
Der Text wird auf ein Bitmap ausgegeben (LBmp1) dabei wird darauf geachtet das die Hintergrundfarbe ungleich der Textfarbe ist. Anschließend wird Pixel für Pixel des Bildes wo die schrift drauf ist (LBmp1) durchgegangen und wenn die Farbe des Pixels ungleich der Hintergrundfarbe ist (also Text an der Stelle ist), wird dieses Pixel mit der Farbe des Hintergrundbildes (ADest) gemicht und dann auf dem Hintergrund (ADest ) ausgegeben. |
Re: halbtransparenten text auf TImage?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:25 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