![]() |
RGB zu Alpha
Kann jemand helfen ?
Mein Versuch..
Delphi-Quellcode:
Das Problem ist einmal funktioniert es dann wieder nicht!
function Rgb2Alpha(colrRGB: Colorref): Byte;
begin if colrRGB <> 0 then Result := LOBYTE(round(colrRGB * 0.2989)) + LOBYTE(round((colrRGB shr 8) * 0.5870)) + LOBYTE(round((colrRGB shr 16) * 0.114)) else Result := 0; end; procedure TSkinEngine.SetupAlphaChannel(DC: HDC); var bm: BITMAP; P: integer; Alpha: byte; pBits: PByte; begin FillChar(bm, sizeof(bm), 0); GetObject(GetCurrentObject(DC, OBJ_BITMAP), sizeof(bm), @bm); pBits := bm.bmBits; for P := 0 to (bm.bmWidth * bm.bmHeight) -1 do begin Alpha := (Rgb2Alpha(RGB(pBits[2], pBits[1], pBits[0])) and $000000FF); if ((Alpha = 0) and (pBits[3] = 0)) then pBits[3] := 0 else if (pBits[3] = 0) then pBits[3] := 255; inc(pBits, 4); end; end; Das erste schlecht das zweite gut. gruss |
AW: RGB zu Alpha
Alpha in Zusammenhang mit RGB ist die Transparenz und die kann man aus dem RGB-Wert nicht berechnen, denn diese wäre eine zusätzliche Angabe.
|
AW: RGB zu Alpha
Zitat:
Kann man doch sehen am Bild ;) gruss |
AW: RGB zu Alpha
Danke ist erledigt habe es gefixt.
1. Pic vorher 2.Pic Aktuell gruss |
AW: RGB zu Alpha
ARGB,
für die, welche die die Lösung nicht mitbekommen haben. |
AW: RGB zu Alpha
Zitat:
ARGB hat damit nichts zu tun.. Wenn ihr die Function richtig interpretieren würdet dann könnt ihr sehen das ich alle von außen sichtbaren Schwarzen Pixel nach Alpha 0 konvertiere.. Also RGB zu Alpha und dafür benötige ich den Alpha wert nicht da ich ihn selbst erstelle. Aber egal ist erledigt. gruss |
AW: RGB zu Alpha
himitsu und Schokohase ihr Ketzer! EWeiss kann Wasser in Wein verwandeln.
|
AW: RGB zu Alpha
Zitat:
|
AW: RGB zu Alpha
Alpha kann auch höchster Wert im RGB Spektrum bedeuten (highbit), bei Pixel x/y. Da ich eh falsch liege in Bezug zu EWeiss hab ichs nicht erwähnt.
|
AW: RGB zu Alpha
Zitat:
Delphi-Quellcode:
Alpha := (Rgb2Alpha(RGB(pBits[2], pBits[1], pBits[0])) and $000000FF);
Aber nochmal es geht darum alle schwarzen Pixel zu entfernen. Also wenn Alpha 0 ist dann wird pBits.rgbReserved auf 0 gesetzt ( := pBits[3]) also komplett durchsichtig. Die Farbe schwarz in dem Fall wird mit dem Alpha Wert 0 ersetzt. andernfalls pBits.rgbReserved := 255 Und deshalb kann ich Wasser in Wein verwandeln. gruss |
AW: RGB zu Alpha
Das Ganze würde ich dann besser gleich 'TransparentColor' nennen.
|
AW: RGB zu Alpha
Zitat:
gruss |
AW: RGB zu Alpha
Wenn man Alpha (siehe
Delphi-Quellcode:
) und
Rgb2Alpha
![]()
Delphi-Quellcode:
als Wert zurückliefert) gleichsetzt, dann ist es auch kein Problem Wasser in Wein zu verwandeln.
Rgb2Alpha
Man definiert einfach, dass Wasser = Wein ist. So einfach kann die Welt sein, oder auch einsam, denn ein sinnvoller Dialog wird so erschwert bis unmöglich, setzt selbiger doch voraus, dass man eine gemeinsame Sprache hat. Dort ist dann Wein ein alkoholisches Getränk und definitiv etwas anderes als Wasser. |
AW: RGB zu Alpha
Zitat:
Wenn ich das richtig verstehe, errechnest du mit "Rgb2Alpha" für jedes Pixel aus den RGB-Werten einen "Grau-Wert. Wenn dieser = 0 (Schwarz) ist und pBits[3] = 0 ist, denn setzt du pBits[3] = 0 (Warum eigentlich= ist doch schon 0) andernfalls, wenn der Grau-Wert <> 0 ist und pBits[3] = 0 ist dann setzt du pBits[3] = 255. Problem dürfte sein, dass Deine "Rgb2Alpha" nicht korrekt arbeitet. So sollte die korrekte Ergebnisse liefern:
Delphi-Quellcode:
function Rgb2Alpha(colrRGB: Colorref): Byte;
begin if colrRGB <> 0 then // Result := LOBYTE(round(colrRGB * 0.2989)) + LOBYTE(round((colrRGB shr 8) * 0.5870)) + // LOBYTE(round((colrRGB shr 16) * 0.114)) Result := round(colrRGB and $FF * 0.2989) + round(colrRGB shr 8 and $FF * 0.5870) + round(colrRGB shr 16 * 0.114) else Result := 0; end; |
AW: RGB zu Alpha
Nö ich berechne keinen Grau wert.
Wenn dem so wäre würde ich RGB2Gray verwenden. Zitat:
![]() Das zweite Bild.. Nun was arbeitet da nicht korrekt? Du siehst den unterschied? gruss |
AW: RGB zu Alpha
Zitat:
zum Beispiel hier ![]() Nur ist es bei dir fehlerhaft programmiert. Was du willst ist doch die Summe aus RGB.Red*0.2689 + RGB.Green*0.587 + RGB.Blue*0.114 Und das ist der Grau-Wert oder die Intensity oder Luminanz etc. Aber deine Funktion rechnet eben etwas anderes, und ich vermute ungewollt. |
AW: RGB zu Alpha
Zitat:
Aber du kannst ja mal erklären was deine RGB2Alpha tatsächlich rechnen soll. Ich würde das gerne verstehen. |
AW: RGB zu Alpha
Hallo AW
1. du schreibst:
Delphi-Quellcode:
Etwas vereinfacht geschrieben:
if ((Alpha = 0) and (pBits[3] = 0)) then
pBits[3] := 0 else if (pBits[3] = 0) then pBits[3] := 255;
Delphi-Quellcode:
Dies kannst du vereinfachen:
if (a=0) and (p=0) then p := 0 else if (p=0) then p:= 255;
Delphi-Quellcode:
D.h. du musst deine function Rgb2Alpha(colrRGB: Colorref): Byte; nur genau dann aufrufen, wenn p=0 ist.
if (p=0) then if (a>0) then p := 255;
2. Deine Funktion Rgb2Alpha berechnet in der Tat die Luminanz eines Pixels. ![]() https://de.wikipedia.org/wiki/Luminanz Da du nur daran interessiert bist, ob Rgb2Alpha 0 zurück liefert oder nicht kannst du deine Funktion Rgb2Alpha ganz wesentlich vereinfachen. 3. Ich empfehle beim Umsetzen von Formeln wie s = a + b + c nach Delphi die Funktion round - wegen der speziellen Art zu runden - nicht zu verwenden. Und wenn's unbedingt sein muss dann so: s = round( a + b + c ) und nicht s = round(a) + round(b) + round(c). Im vorliegenden Fall (Berechnung Luminanz) spielt es zwar keine Rolle. Wenn aber wenn a = 12.5, b = 10.5, c = 2.5 dann ist s = 25.5. s = round( 25.5 ) = 26. Hingegen: s = round(12.5) + round(10.5) + round(2.5) = 24. Gruss M |
AW: RGB zu Alpha
Zitat:
Delphi-Quellcode:
Nur dann hole ich mir die werte.
function Rgb2Alpha(colrRGB: Colorref): Byte;
begin if colrRGB <> 0 then Einen 0 wert berechnen zu wollen macht keinen sinn der bleibt immer 0.
Delphi-Quellcode:
s := round( a + b + c )
Jo ist sinnvoll wenn es ginge. Denn ich multiplizier zu Colorref einen single type deshalb muss ich bei jedem (colrRGB * 0.2989) ein Round vorsetzen. Das! Wird nix
Delphi-Quellcode:
Result := Round(LOBYTE(colrRGB * 0.2989) + LOBYTE((colrRGB shr 8) * 0.5870) +
LOBYTE((colrRGB shr 16) * 0.114))) Zitat:
Zitat:
gruss |
AW: RGB zu Alpha
Zitat:
Du (AW) rufst deine Rgb2Alpha in jedem Fall auf und rechnest dann im Fall RGB>0 weiter. Ich (MG) rufe deine Funktion nur im Fall (p[3]=)A=0 auf und rechne im Fall RGB>0 weiter.
Delphi-Quellcode:
Wenn das Quell-Bild also bereits Alphawerte enthält, gewinne ich viel Zeit.
RGB A AW MG
0 0 f f >0 0 R R 0 >0 f - >0 >0 R - Da du nur an 0 oder nicht 0 interessiert bist, könntest du alpha so oder ähnlich beschleunigen:
Delphi-Quellcode:
function alpha( r, g, b : integer ) : integer;
begin result := 0; if (r>=2) or (g>=1) or (b>=5) then result := 255 else if (299*r + 587*g + 114*b >= 500) then result := 255; end; Oder deine Funktion etwas beschleunigen, indem du beim Aufruf nicht zuerst die drei Bytes R,G,B zusammenfasst, um sie dann in der Funktion wieder auseinander zu rechnen. Ich bin hier wieder weg... Viel Spass bei deinen coolen Projekten. |
AW: RGB zu Alpha
[QUOTE=EWeiss;1411152]
Zitat:
Mach mal
Delphi-Quellcode:
// Rgb2Alpha ist die in #1 gezeigte Funktion.
ShowMessage(IntToStr(Rgb2Alpha($FFFFB1)));
Und dann
Delphi-Quellcode:
ShowMessage(IntToStr(Rgb2Alpha(0)));
Bei mir kommt da in beiden Fällen 0 heraus. Und nun erklär mit mal, warum Deine "Rgb2Alpha" bei $FFFFB1 (ein sehr helles Cyan) und bei 0 (Schwarz) den gleichen Wert zurückgibt. |
AW: RGB zu Alpha
Zitat:
![]() Und erkenne um was es dabei geht. Das Thema ist jetzt wirklich beendet für mich. Aber ihr könnt gerne weiter diskutieren. :) gruss |
AW: RGB zu Alpha
Hallo AW,
doch noch rasch: Apro hat schon Recht; deine Funktion berechnet den Luminanz Wert für die meisten der 256^3 möglichen RGB Werte nicht korrekt. Sehr einfach kannst du es testen, indem du mit deiner Funktion die Luminanz-Werte von RGB(grau,grau,grau) für grau=0 bis 255 berechnest. Welche Werte sollte deine Funktion liefern? In E'Y = 0,299 E'R + 0,587 E'G + 0,114 E'B eingesetzt ergibt sich Y(grau) = 0,299*grau + 0,587*grau + 0,114*grau = grau = id Deine Funktion liefert jedoch meistens andere Werte (weil du nicht wie Apro dir vorschlägt das jeweilige Farbbyte mittels "and $ff" separierst):
Delphi-Quellcode:
procedure TForm71.Button1Click(Sender: TObject);
var w, grau : byte; s : string; begin s := ''; for grau := 0 to 255 do begin w := Rgb2Alpha2( RGB( grau, grau, grau ) ); s := s + w.ToString + ', '; end; showmessage( s ); end; |
AW: RGB zu Alpha
Zitat:
Werde "and $FF" addieren damit sollte das Problem beseitigt sein. Dachte eigentlich das ich mir das $FF durch das LOBYTE ersparen konnte. Wenn dem nicht so ist gut dann habe ich wieder was gelernt. Aufgrund dieser Annahme bin ich davon ausgegangen das meine Berechnung korrekt war. (Nun gut Danke man ist nicht perfekt ;) ) PS: Sichtbare unterschiede kann ich jedoch nicht ausmachen, zwischen deiner und meiner vorherigen Berechnung. Egal welche zwischen Werte am ende bei der Berechnung umhinkommen am ende zählt doch nur ob das Ergebnis 0 ist um die schwarzen Pixel zu entfernen. Alle anderen Farbigen Pixel bleiben erhalten. Das einzige Problem das ich nun noch habe ist das bei 16Farbigen Icons schwarz komplett entfernt wird. Siehe shot! gruss |
AW: RGB zu Alpha
Delphi-Quellcode:
kannst du schon nehmen, allerdings wirkt es in deiner Formel zu spät.
LOBYTE
|
AW: RGB zu Alpha
Zitat:
gruss |
AW: RGB zu Alpha
Dein Original
Delphi-Quellcode:
müsste eigentlich so aussehen
Result := LOBYTE(round(colrRGB * 0.2989)) +
LOBYTE(round((colrRGB shr 8) * 0.5870)) + LOBYTE(round((colrRGB shr 16) * 0.114));
Delphi-Quellcode:
Und wenn wir schon dabei sind:
Result := round(LOBYTE(colrRGB) * 0.2989) +
round(LOBYTE(colrRGB shr 8) * 0.5870) + round(LOBYTE(colrRGB shr 16) * 0.114);
Code:
Wo ist also der Unterschied ob ich die Luminanz mit
19595 => 0.2989 * 65536
38470 => 0.5870 * 65536 7471 => 0.1440 * 65536
Code:
berechne oder mit
l = 0.2989 * r + 0.5870 * g + 0.1440 * b
Code:
Genau, es gibt keinen Unterschied, beide Formeln berechnen exakt das Gleiche.
l = ( 19595 * r + 38470 * g + 7471 * b ) / 65536
|
AW: RGB zu Alpha
Zitat:
Danke. gruss |
AW: RGB zu Alpha
Was ich mich die ganze Zeit frage, reicht es nicht aus clFuchsia als Transparent Farbe zu setzen für Icons?
|
AW: RGB zu Alpha
Zitat:
Systemweit? Ich muss die Farbe nehmen die vom Icon übergeben wird nicht eine die ich mir wünsche. Kann den Leuten doch nicht diktieren mit welcher Hintergrundfarbe die ihre Icons zeichnen die sind nun mal so ;) gruss |
AW: RGB zu Alpha
Standard ist eigentlich die Farbe eines Eckpixels als Transparenz anzunehmen. Ich glaube es war die linke untere Ecke. Kann mich aber auch täuschen.
Edith fand in den Microsoft Richtlinen zum Icon Design "Use magenta (R255 G0 B255) as the background transparency color." Sherlock |
AW: RGB zu Alpha
|
AW: RGB zu Alpha
Also wenn ich ein Icon habe, Neon-Rote Umrandung mit Transparenz in der Mitte würde mir doch eine Abfrage nach oben/links <> unten/links in beiden Fällen meinen Rahmen löschen, da muss ich noch mal lesen oder ich verstehe das gerade falsch.
Gehört ja eh nicht hier rein, tut mir leid. |
AW: RGB zu Alpha
Hallo AW
du schreibst, dass du die Luminanz und nicht den Grauwert verwenden willst. Vergleiche aber ![]() und ![]() Deine in #24 gepostete Funktion function TSkinEngine.Rgb2Gray(RGBValue: COLORREF): COLORREF; stdcall; liefert dir also die von dir gesuchte Luminanz wie Schokohase in #27 zeigt. Deine ursprüngliche Funktion hat auch extrem helle Farben wie RGB( 250 253 241 ) als sehr dunkel (0) bewertet. Du hast in #24 eine Grafik gepostet, schwarz wird dort durch deine Funktion unsichtbar. Das ist doch genau das, was du von deiner Funktion erwartest. Wenn du bereits vorhandene Icons korrekt darstellen willst, dann bringt dein Weg über "sehr dunkle Pixels => unsichtbar setzen" natürlich nicht den gewollten Effekt. Gruss |
AW: RGB zu Alpha
Zitat:
Du vergisst eins dabei das dieses keinen Alphawert kennt also in dem sinne da nur 16 Farben enthalten sind. Bei meinem Hochauflösenden Icon von meinem Piano gibt es das Problem nicht und das ist komplett schwarz. Das müsste dann deiner Meinung nach komplett unsichtbar sein. ;) Ich bleibe bei meiner Funktion Rgb2Alpha auch wenn Rgb2Gray fast das gleiche ist. :) Irgendwann muss mal Schluss sein sonst beschäftige ich mich die nächsten 10 Jahre noch damit. :coder: gruss |
AW: RGB zu Alpha
Ich vermute, dass dein "schwarzes Piano Bild" bereits Alphakanalwerte enthält BEVOR du dieses Bild deiner "...toAlpha" Bearbeitung fütterst. Dann macht deine Bearbeitung genau nix:
Wenn dem so ist, dann behältst du ja die bereits vorhandenen p>0 AlphaWerte des Bilds bei und beachtest das Funktionsresultat von "...toAlpha" ausschliesslich im Fall p=0 (transparent) - und wenn du im Fall p=0 Glück hast und an den p=0 Stellen der RGB Wert 0 ist, bleibt dein Icon durch deine Bearbeitung komplett unverändert. if (p=0) then if (...toAlpha > 0) then p := 255; Bei deinem "schwarzen Käfer Bild" hingegen fehlt der Alphakanal und du fügst einen Alphakanal mit deiner Bearbeitung hinzu. Dabei gilt: Genau alle Pixel, welche Helligkeit 0 aufweisen werden durch deine Bearbeitung durchsichtig. Deshalb erscheint die schwarze Farbe des Käfers transparent. Wie erwähnt: Wenn du bereits bestehende Icons irgendwo hinmalen willst, dann ist es sicher besser, wenn du die Icons vor dem Anzeigen nicht mit deiner ...toAlpha bearbeitest. |
AW: RGB zu Alpha
Wenn ich mich recht entsinne galt "früher" für Windows Icons, insbesondere denen mit nur 16 Farben, dass clFuchsia als "Key"-Farbe, also Transparenz definiert wurde. Darüber hinaus gab es auch die Variante, dass eine zusätzliche 1-Bit Maske ergänzend zu dem Bitmap in der Datei ist. Bei moderneren Icons, insbesondere denen die intern als PNG hinterlegt sind und 32bpp haben, gibt es gleich einen kompletten 8 Bit Alphakanal der fest zum Bild gehört.
Wenn es sich also wirklich um Icons im Sinne von "liegt als .ico-Datei vor" handelt, dürfte das ganze eigentlich ohne jede "künstliche Generierung" von Transparenzen abhandelbar sein. Von daher bin ich etwas verwundert darüber, warum du das überhaupt machst. Edit: Michaels Beitrag geht da in dieselbe Richtung würde ich schätzen. |
AW: RGB zu Alpha
Zitat:
![]() Zitat:
Was ist denn nun besser das erste oder zweite Icon. :cyclops: Zitat:
gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:28 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