e1st33
Anmeldungsdatum: 11. Juni 2016
Beiträge: Zähle...
|
Moin.... ich bin ein Python Anfänger und wollte mich damit mal beschäftigen. Mein ziel ist es, unter einem Pi3, ein Programm zu haben das es mit ermöglicht die Farbe die sich unter dem Mauszeiger ist zu erkennen und zu notieren. Im Sinne von : 35 Sekungen Warten
Farbe erkennen → Notieren
35 Sekunden Warte Ich hoffe jemand kann mir weiter helfen ☺
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29453
Wohnort: WW
|
Hallo, ...und willkommen bei ubuntuusers.de. Zu deinem Problem: das ist wahrscheinlich schon lösbar, aber da müsste selbst ein Programmierprofi drüber nachdenken, weil das alles andere als trivial ist. Und selbst als Python-Fanboy würde ich hier sagen: für diese Aufgabe würde ich kein Python nehmen.
ich bin ein Python Anfänger und wollte mich damit mal beschäftigen.
Dann beschäftige dich doch mal mit etwas einfachen ☺ Und nicht mit etwas, für das man rel. tief in System und den XServer abtauchen muss. Gruß, noisefloor
|
Vain
Anmeldungsdatum: 12. April 2008
Beiträge: 2503
|
Abriss der Technologien, die dir weiterhelfen könnten: Ich verstehe das so, dass du auf deinem Raspberry Pi3 einen normalen X-Server laufen hast. Du wirst also für den Vorhaben einen X-Client programmieren. Dazu kannst du entweder ein XLib-Binding für Python nehmen oder du nimmst das modernere XCB. (Gibt es bestimmt. Ich habe X-Clients bisher aber immer in C geschrieben.) Da du eh nur alle paar Sekunden aktiv werden willst, kannst du mit dem normalen XLib-Call „XQueryPointer() “ die aktuelle Mausposition abfragen. (Würdest du einen konstanten Stream der Mauspositionen haben wollen – sie als direkt verfolgen wollen –, dann wäre XInput2 besser geeignet.) Um die Farbe unter dem Mauszeiger ermitteln zu können, kannst du einen Screenshot machen. Habe ich persönlich noch gar nicht ausprogrammiert, aber „XGetImage() “ scheint hier der Ansatzpunkt zu sein.
– edit: Ich stimme zu, dass das ganz schön viele Themen auf einmal sind, wenn du gerade erst Anfänger bist. Möglicherweise überfordernd viel. Zumal die überwiegende Masse an X-Clients in C geschrieben ist, weshalb du viel Transferarbeit leisten müssen wirst, wenn du das in Python machen willst. Aber wie immer: Wenn man weiß, was man machen muss, ist es nicht so schwer. So geht’s in C: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 | #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int
main(int argc, char **argv)
{
Display *dpy;
int mouse_x, mouse_y, di, dx, dy;
int screen, width, height;
unsigned char red, green, blue;
unsigned int dui;
unsigned long pixel;
Window child, dummy;
Window root;
XEvent ev;
XImage *xim = NULL;
XWindowAttributes gwa;
dpy = XOpenDisplay(NULL);
if (!dpy)
{
fprintf(stderr, "Cannot open display\n");
exit(EXIT_FAILURE);
}
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
XGetWindowAttributes(dpy, root, &gwa);
width = gwa.width;
height = gwa.height;
for (;;)
{
XQueryPointer(dpy, root, &dummy, &child, &mouse_x, &mouse_y, &di, &di, &dui);
xim = XGetImage(dpy, root, 0, 0, width, height, AllPlanes, ZPixmap);
if (xim)
{
pixel = XGetPixel(xim, mouse_x, mouse_y);
red = (pixel & 0xFF0000) >> 16;
green = (pixel & 0xFF00) >> 8;
blue = pixel & 0xFF;
printf("Color under cursor: #%02X%02X%02X\n", red, green, blue);
XDestroyImage(xim);
}
/* Discard pending events */
while (XPending(dpy))
XNextEvent(dpy, &ev);
sleep(1);
}
/* unreached */
}
|
(Ich poste das nicht, um dir den Spaß zu verderben, sondern weil ich darauf hoffe, dass du am Ball bleibst und versuchen wirst, das Problem in Python zu lösen. Den Code hier kannst du dann als Stütze verwenden. Ich behaupte mal ganz arrogant 😬, dass es auch so noch herausfordernd genug werden könnte.) (– edit 2: Und ich fand die Aufgabe interessant. 😀)
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4636
Wohnort: Berlin
|
@Vain: Ein Bildschirmfoto vom gesamten Bildschirm zu machen, obwohl man davon nur ein Pixel haben möchte, erscheint mir ein wenig übertrieben. XGetImage(dpy, root, mouse_x, mouse_y, 1, 1, AllPlanes, ZPixmap) sollte eigentlich reichen. Das ganze ist mit der C-Vorlage gar nicht schwer nach Python zu portieren:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | #!/user/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
from time import sleep
from Xlib import X
from Xlib.display import Display
def main():
display = Display()
try:
root = display.screen().root
while True:
pointer = root.query_pointer()
image = root.get_image(
pointer.root_x, pointer.root_y, 1, 1, X.ZPixmap, 0xffffffff
)
pixel = map(ord, image.data)
print('Color under pointer (BGRA format):', pixel)
while display.pending_events():
display.next_event()
sleep(1)
finally:
display.close()
if __name__ == '__main__':
main()
|
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29453
Wohnort: WW
|
Hallo, da es exakt den gleichen Thread von selben TE auch im deutschen Python-Forum gibt (wodurch Marc_BlackJack_Rintsch wohl auch erst auf das Thema aufmerksam geworden ist 😉 ), hier noch der Querverweis dorthin: https://www.python-forum.de/viewtopic.php?f=6&t=38688 Gruß, noisefloor NACHTRAG: auch wenn die pythonische Lösung rel. kurz ist und einfach aussieht - IMHO ist das nichts, was man als Python-Einsteiger so hinbekommt.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4636
Wohnort: Berlin
|
Nein, das hätte man als blutiger Einsteiger wahrscheinlich nicht so leicht hinbekommen. Darum die Komplettlösung ohne irgendwelche Versuche den OP auch selbst was lösen zu lassen. ☺ Ich hatte mich da in einer IPython-Shell ”live” heran getastet. Also die Module aus Xlib importiert und dann geschaut was von den Namen her an das C-Programm heran kommt. Der grösste Stolperstein war XGetImage() aus C versus Window.get_image() in Python, weil da die letzten beiden Parameter vertauscht sind und es gibt keine AllPlanes -Konstante. (Oder ich war zu blind die zu finden.) Wegen der Parameter ein Blick in die Dokumentation von XGetImage() weiter geholfen.
|
e1st33
(Themenstarter)
Anmeldungsdatum: 11. Juni 2016
Beiträge: 2
|
Marc_BlackJack_Rintsch schrieb: @Vain: Ein Bildschirmfoto vom gesamten Bildschirm zu machen, obwohl man davon nur ein Pixel haben möchte, erscheint mir ein wenig übertrieben. XGetImage(dpy, root, mouse_x, mouse_y, 1, 1, AllPlanes, ZPixmap) sollte eigentlich reichen. Das ganze ist mit der C-Vorlage gar nicht schwer nach Python zu portieren:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | #!/user/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
from time import sleep
from Xlib import X
from Xlib.display import Display
def main():
display = Display()
try:
root = display.screen().root
while True:
pointer = root.query_pointer()
image = root.get_image(
pointer.root_x, pointer.root_y, 1, 1, X.ZPixmap, 0xffffffff
)
pixel = map(ord, image.data)
print('Color under pointer (BGRA format):', pixel)
while display.pending_events():
display.next_event()
sleep(1)
finally:
display.close()
if __name__ == '__main__':
main()
|
Moin ☺ Ersteinmal Danke für die Infos ☺. Könnte ich dieses jetzt 1:1 Übernehmen sodass auch eine log datei erstellt wird? lg. Alex
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29453
Wohnort: WW
|
Hallo,
Könnte ich dieses jetzt 1:1 Übernehmen sodass auch eine log datei erstellt wird?
Klar. Dafür musst du nur die Zeile, in der die Farbe mittels print ausgegeben werden durch ein paar Zeilen ersetzen, die die Farbe in eine (Log-) Datei schreiben. Das ist ein Aufgabe, die man auch als Anfänger lösen kann ☺ Gruß, noisefloor
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4636
Wohnort: Berlin
|
Da der Trend ja anscheinend weg von xlib und hin zu libxcb geht, hier das ganze noch mal mit dieser Anbindung an das X-Protokoll: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | #!/user/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
from time import sleep
import xcb
import xcb.xproto
from xcb.xproto import ImageFormat
def main():
connection = xcb.connect()
try:
root = connection.get_setup().roots[0]
while True:
pointer = connection.core.QueryPointer(root.root).reply()
image = connection.core.GetImage(
ImageFormat.ZPixmap,
root.root,
pointer.root_x,
pointer.root_y,
1,
1,
0xffffffff
).reply()
pixel = list(image.data)
print('Color under pointer (BGRA format):', pixel)
sleep(1)
finally:
connection.disconnect()
if __name__ == '__main__':
main()
|
|