"Grundfarbe" aus einem Icon ermittlen

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Benutzeravatar
ssemleit
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 123
Registriert: Di, 08. Mär 2016 11:32
Hat sich bedankt: 18 Mal
Danksagung erhalten: 8 Mal

"Grundfarbe" aus einem Icon ermittlen

Beitrag 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 :D

Beispiel anhand 3 Icons:
icons.png
icons.png (2.86 KiB) 2606 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
Gruß
Stefan
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9339
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 99 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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.
Herzlich,
Tom
Benutzeravatar
ssemleit
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 123
Registriert: Di, 08. Mär 2016 11:32
Hat sich bedankt: 18 Mal
Danksagung erhalten: 8 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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.
Gruß
Stefan
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9339
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 99 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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.
Herzlich,
Tom
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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
gruss by OHR
Jimmy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9339
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 99 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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?
Herzlich,
Tom
Benutzeravatar
ssemleit
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 123
Registriert: Di, 08. Mär 2016 11:32
Hat sich bedankt: 18 Mal
Danksagung erhalten: 8 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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
Kunde.png (2.53 KiB) 2545 mal betrachtet
Der Hintergrund soll anstelle des hellen blau hier ein helles grün werden.
Lieferant.png
Lieferant.png (2.46 KiB) 2545 mal betrachtet
Der Hintergrund soll anstelle des hellen blau hier ein helles gelbwerden.
Gruß
Stefan
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9339
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 99 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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.
Herzlich,
Tom
Benutzeravatar
ssemleit
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 123
Registriert: Di, 08. Mär 2016 11:32
Hat sich bedankt: 18 Mal
Danksagung erhalten: 8 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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.
Gruß
Stefan
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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() )
Zuletzt geändert von AUGE_OHR am Mi, 15. Feb 2023 15:39, insgesamt 1-mal geändert.
gruss by OHR
Jimmy
Benutzeravatar
ssemleit
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 123
Registriert: Di, 08. Mär 2016 11:32
Hat sich bedankt: 18 Mal
Danksagung erhalten: 8 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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
Gruß
Stefan
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9339
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 99 Mal
Danksagung erhalten: 357 Mal
Kontaktdaten:

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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.
Herzlich,
Tom
Benutzeravatar
ssemleit
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 123
Registriert: Di, 08. Mär 2016 11:32
Hat sich bedankt: 18 Mal
Danksagung erhalten: 8 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag von ssemleit »

Danke Tom.
Dann versuch ich mal, Rogers Code auseinanderzunehmen und für mich zu verwenden.

Gruß
Stefan
Gruß
Stefan
Benutzeravatar
ssemleit
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 123
Registriert: Di, 08. Mär 2016 11:32
Hat sich bedankt: 18 Mal
Danksagung erhalten: 8 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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
kdli.png (5.64 KiB) 2900 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
Gruß
Stefan
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 841
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 38 Mal
Danksagung erhalten: 188 Mal
Kontaktdaten:

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag 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

Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Benutzeravatar
ssemleit
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 123
Registriert: Di, 08. Mär 2016 11:32
Hat sich bedankt: 18 Mal
Danksagung erhalten: 8 Mal

Re: "Grundfarbe" aus einem Icon ermittlen

Beitrag von ssemleit »

Hallo Marcus,

danke, die Funktion TransformColor() tut was es soll.

Gruß
Stefan
Gruß
Stefan
Antworten