Seite 1 von 1
"Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 8:36
von ssemleit
Hallo,
ich suche eine Möglichkeit aus einem Icon die "Grundfarbe" oder "Durchschnittsfarbe" zu ermitteln.
Die Begriffe hab ich mir wohl gerade ausgedacht
Beispiel anhand 3 Icons:
- icons.png (2.86 KiB) 3320 mal betrachtet
Für das 1. Icon soll "grün", für das 2. Icon "gelb" und für das 3. Icon "blau" als RGB-Werte ermittelt werden.
Das möchte ich dazu nutzen, um in Dialogen bestimmte Bereiche in den Farben einfärben.
Gruß
Stefan
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 9:01
von Tom
Mmh. Noch nie probiert, aber Du kannst aus den als XbpIcons geladenen Icons die XbpBitmap-Objekte erzeugen (:GetBitmap) und aus denen wiederum z.B. die Standard-Hintergrundfarbe mit ":getDefaultBGColor" auslesen. Ansonsten müsstest Du Bildpunkt für Bildpunkt die Farbe erheben, und die, die am häufigsten vorkommt, ist die gesuchte.
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 9:08
von ssemleit
Ich habe auch schon daran gedacht, das Icon irgendwo hin zu pinseln und dann für alle Punkte (oder in einem Raster)
die einzelnen RGB Werte zu addieren (Hintergrundfarbe lass ich aus) und durch die Anzahl der "Messungen" zu teilen.
Nur hab ich nicht griffbereit, wie ich die Farbe eines Pixels ermitteln kann.
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 9:51
von Tom
Die Pixel bestehen ja nur aus Farbe und sonst nichts - jeder Punkt ist Farbe. Irgendwo im Forum hat jemand (mit mehr als 90%iger Sicherheit würde ich vermuten: Jimmy) mal gezeigt, wie man Bitmaps pixelweise liest und auswertet.
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 12:33
von AUGE_OHR
hi,
es gibt die API Function GetPixel()
https://learn.microsoft.com/en-us/windo ... i-getpixel
Code: Alles auswählen
DLLFUNCTION GetPixel( hDC, nX, nY ) USING STDCALL FROM GDI32.DLL
oDlg:Static1:lbDown := {|aPos,uNIL,oSelf| oDlg:ShowColor(aPos)}
Code: Alles auswählen
METHOD DemoDlg:create( oParent, oOwner, aPos, aSize, aPP, lVisible )
// hDC need for DLLcall
::hDC := ::Static1:winDevice():getHDC()
// use :paint callback slot to repaint
::Static1:paint := {|aRect,uNIL,oSelf| ::StaticPaint() }
Code: Alles auswählen
METHOD DemoDlg:ShowColor(aPos)
LOCAL nColor := GetPixel(::hDC,aPos[1],aPos[2])
LOCAL aRGB := GraGetRGBIntensity(AutomationTranslateColor(nColor,.T.))
Msgbox("Color "+VAR2CHAR(aRGB),"Position "+VAR2CHAR(aPos) )
RETURN nil
p.s. bei 0,0 bekommt man die Farbe für "Transparency" also ab 1,1 die Farbe abfragen
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 13:13
von Tom
Ja, aber GetPixel benötigt einen DeviceContext, also eine Drawingarea. Das geht (und man kann es automatisieren), wenn die Icons tatsächlich angezeigt werden, aber ist das auch, wonach Du suchst, Stefan?
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 13:59
von ssemleit
So wie ich das verstehe, ist der Tipp von Jimmy sowas ähnliches wie ein ColorPicker, der eine Anzeige auf dem Bildschirm benötigt.
D.h. wenn das Element nicht sichtbar ist, kann ich auch nix von meinem Icon auslesen.
Da hab ich dann das Henne<>Ei Problem.
Ich habe ein XbpStatic und zeichne per Ownerdrawing mit XbpIcon:draw() das Icon und u.a. per GraBox() eine Box.
Die Box soll als Farbe die um einiges aufgehellte "Grundfarbe" des Icons haben.
- Kunde.png (2.53 KiB) 3259 mal betrachtet
Der Hintergrund soll anstelle des hellen blau hier ein helles grün werden.
- Lieferant.png (2.46 KiB) 3259 mal betrachtet
Der Hintergrund soll anstelle des hellen blau hier ein helles gelbwerden.
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 14:17
von Tom
Wenn Du die Koordinaten des Icons kennst (was der Fall sein dürfte - Du malst es ja per Ownerdrawing), kannst Du Jimmys Methode verwenden. Du zeichnest ja auf einen PS, und der liefert einen DeviceContext. Du musst nur das Icon abarbeiten, die verschiedenen Farben sammeln und die am häufigsten verwendete nutzen. Das dürfte auch ziemlich schnell gehen. Wenn Du das aber vor dem Zeichnen der Icons wissen willst, musst Du ein bisschen anders vorgehen.
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 14:21
von ssemleit
Ich werde mal mein Glück versuchen.
Da ich jedoch erst die Box zeichne und darauf dann das Icon bin ich noch etwas skeptisch, ob ich damit Erfolg habe.
Weil für die Box brauch ich die Farbe vom Icon. Ich werde berichten...
Danke Tom und Jimmy.
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 15:30
von AUGE_OHR
hi,
hast du links eine 2nd Monitor
wenn Nein kannst du "negative" Koordinaten verwenden die man nicht "sehen" kann
wenn es "fertig" ist schiebst du es auf die richtige Position
---
man kann ein MemoryDC nutzen um alles im Speicher zu machen
Frage : arbeitest du mit Express++
ich "glaube" Roger hat mal ein Beispiel für Eugene mit Express++ gemacht
ich muss mal suchen wo das ist ...
---
Nachtrag : für den Device Context kann man auch das nehmen
Code: Alles auswählen
DLLFUNCTION GetWindowDC( hwnd ) USING STDCALL FROM USER32.DLL
hDC1 := GetWindowDC( o:getHWnd() )
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 15:38
von ssemleit
Hallo Jimmy,
ich habe mehrere Bildschirme. Je nach Kundeninstallation kann das durchaus auch vorkommen.
MemoryDC sagt mir leider nix.
Express++ verwende ich nicht.
Das Auslesen der RGB-Werte mittels Deiner Funktion ShowColor(aPos) klappt prima!
Gruß
Stefan
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 15:41
von Tom
Hier:
http://bb.donnay-software.com/donnay/vi ... 364#p10364
Das basiert zwar auf eXpress++, aber die eigentlich verwendete Funktionalität ist unabhängig davon.
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Mi, 15. Feb 2023 15:49
von ssemleit
Danke Tom.
Dann versuch ich mal, Rogers Code auseinanderzunehmen und für mich zu verwenden.
Gruß
Stefan
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Do, 16. Feb 2023 9:55
von ssemleit
Also, die Grundfarbe ermitteln klappt jetzt ganz gut.
Das mit dem MemoryDC hab ich mir erst mal gespart und eine Krücke gebaut. Ich Pinsel erst das Icon und dann Hintergrund+Icon.
So sieht jeweils der Hintergrund mit der aus den Icons ermittelten Farbe aus:
- kdli.png (5.64 KiB) 3614 mal betrachtet
Ich würde die Hintergrundfarben aber gerne etwas heller machen.
Hat jemand noch einen Tipp, wie ich aus den RGB-Werten "hellere" RGB-Werte bekomme?
Gruß
Stefan
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Do, 16. Feb 2023 12:49
von Marcus Herz
Code: Alles auswählen
/*============================================================================
$Function: TransformColor(nColor, nProz)
$Group: 4
$Author: Marcus Herz
$Topic: RGB Farbwert aufhellen oder abdunkeln
$Description: Ein RGB Farbwert kann damit um einen Prozentfaktor aufgehellt oder abgedunkelt werden.
$Argument: nColor RGB Farbwert, z.B. von GraMakeRGBColor()
$Argument: nProz Prozentwert, kleiner 0 = aufhellen, größer 0 = abdunkeln
$Return: nRgbColor
$See Also:
$Example:
// helle Farbe als Hintergrund, abgedunkelte Farbe, wenn sich Cursor in der Zelle befindet
oCol :ColorBlock := {|x,oB,oC| {,GraMakeRGBColor({100,200,45}),,TransformColor(GraMakeRGBColor({100,200,45}),-10)}}
? TransformColor(GraMakeRGBColor({100,200,45}),-10) // entspricht Farbwert {110,220,50}, aber ist heller
// volles rot, aufhellen
? TransformColor(GraMakeRGBColor({255, 0, 0 }), -10) // entspricht Farbwert {255,26,26}, heller
? TransformColor(GraMakeRGBColor({255, 0, 0 }), -100) // entspricht Farbwert {255,255,255}, weiss
==============================================================================*/
FUNC TransformColor(nColor, nProz)
LOCAL nGreen, nBlue, nRed
if band(nColor, 0x1000000 ) = 0 // keine RGB Farbe
RETURN nColor
elseif nProz == 0
RETURN nColor
elseif nProz >= 100
RETURN GraMakeRGBColor({0,0,0})
elseif nProz <= -100
RETURN GraMakeRGBColor({255,255,255})
endif
nRed := band(nColor, 0xFF)
nGreen := band(nColor, 0xFF00)
nBlue := band(nColor, 0xFF0000)
nGreen /= 2**8
nBlue /= 2**16
nProz *= -1 // vorzeichen umdrehen > 255,255,255 ist weiss
if nRed == 0
if nProz > 0
nRed := 255 * nProz / 100
endif
else
nRed := max(0, nRed + nRed * nProz / 100)
endif
if nGreen == 0
if nProz > 0
nGreen:= 255 * nProz / 100
endif
else
nGreen := max(0, nGreen + nGreen * nProz / 100)
endif
if nBlue == 0
if nProz > 0
nBlue := 255 * nProz / 100
endif
else
nBlue := max(0, nBlue + nBlue * nProz / 100)
endif
nColor := min(255, int(nRed))
nColor += min(255, int(nGreen)) * 2**8
nColor += min(255, int(nBlue)) * 2**16
nColor := bor(nColor, 0x1000000) // xbase bit setzen
RETURN nColor
Re: "Grundfarbe" aus einem Icon ermittlen
Verfasst: Do, 16. Feb 2023 13:27
von ssemleit
Hallo Marcus,
danke, die Funktion TransformColor() tut was es soll.
Gruß
Stefan