Farbe von Pixeln ermitteln

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
bas_oldy
User
Beiträge: 16
Registriert: Donnerstag 23. August 2018, 20:09

Hallo Leute,

beim Versuch die Farbe von Pixeln eines Bildes zu ermitteln habe ich mit dem Programm:

import tkinter
root = tkinter.Tk()

cc = tkinter.Canvas(root, width='400', height='200')

cc.create_polygon(0,0,100,0,100,100,0,100,fill="#000000")
cc.create_polygon(0,100,100,100,100,200,0,200,fill="#ffffff")
cc.create_polygon(100,0,200,0,200,100,100,100,fill="#ff0000")
cc.create_polygon(200,0,300,0,300,100,200,100,fill="#00ff00")
cc.create_polygon(300,0,400,0,400,100,300,100,fill="#0000ff")
cc.create_polygon(100,100,200,100,200,200,100,200,fill="#00ffff")
cc.create_polygon(200,100,300,100,300,200,200,200,fill="#ff00ff")
cc.create_polygon(300,100,400,100,400,200,300,200,fill="#ffff00")

cc.pack()


ein Rechteck (Breite 400, Höhe 200) erstellt und darauf acht verschieden gefärbte Quadrate angeordnet. Von dem Rechteck habe ich ein Bildschirmfoto der Größe 400*200 als .jpg-file gesichert.

Wenn ich mit einem zweiten Programm:

from PIL import Image

im = Image.open('Farben.jpg')
pix = im.load()

print (im.size)

print (pix[100,100])
print (pix[300,100])
print (pix[500,100])
print (pix[700,100])

print (pix[100,300])
print (pix[300,300])
print (pix[500,300])
print (pix[700,300])

die Größe des Rechtecks ausdrucken lasse, erhalte ich 800*402 statt 400*200 und nach entsprechender Korrektur der Koordinaten die folgende Angabe der Farben:

Größe:
(800, 402) statt (400, 200)

Farben:
(0, 0, 0) ok
(233, 50, 36) statt (255, 0, 0)
(123, 249, 79) statt (0, 255, 0)
(0, 34, 245) statt (0, 0, 255)
(255, 255, 255) ok
(119, 251, 253) statt (0, 255, 255)
(232, 62, 246) statt (255, 0, 255)
(255, 253, 86) statt (255, 255, 0)

Was mache ich falsch und wie wäre es richtig?

Vielen Dank für eure Hilfe.
NPC
User
Beiträge: 54
Registriert: Dienstag 8. Januar 2019, 17:51

Hallo,

Es wäre schön, wenn du deinen Code in entsprechende tags packen würdest, dann könnte man ihn besser lesen.
Wie genau hast du das Bildschirmfoto denn gemacht (welches tool, ...)?
Warum genau willst du dass denn so machen?
Die Farben gibst du ja oben schon in hex vor daher solltest du sie doch wissen oder was genau ist dein Ziel?

Bei einer so genauen Betrachtung musst du etwas aufpassen. Speichere das lieber als PNG. JPG komprimiert das ganze und dadurch können (je nach verwendeter Methode) informationen verloren gehen was dass Bild dann z.B. farblich verändert. Vielleich hilft dir das: https://de.wikipedia.org/wiki/JPEG weiter.

Viele Grüße
NPC
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@bas_oldy: Anmerkungen zum (ersten) Quelltext:

Es fehlt der `mainloop()`-Aufruf. Ohne den beendet sich das Programm sofort wieder.

Breite und Höhe vom `Canvas` würde ich nicht als Zeichenketten in Python angeben. Tk ist das egal weil Tcl im Grudne sowieso nur Zeichenketten als Datentyp kennt, aber es sind semantisch halt Zahlen und die lassen sich in Python auch durch einen entsprechenden Datentyp ausdrücken. Dann kann man die auch ausrechnen anhand der Anzahl der Farben und wie viele Quadrate man pro Zeile haben möchte.

Was soll der Name `cc` bedeuten? Wenn der `canvas` hiesse, müsste man nicht raten.

Die ganzen Koordinaten würde man auch eher nicht von Hand schreiben wollen, sondern aus Grössen wie der Anzahl der Quadrate pro Zeile, der Grösse eines Quadrats, und des Indexes der Farbe in einer Liste, berechnen.

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter

SQUARE_SIZE = 100
SQUARES_PER_ROW = 4


def main():
    root = tkinter.Tk()
    colors = [
        "#000000",
        "#ff0000",
        "#00ff00",
        "#0000ff",
        "#ffffff",
        "#00ffff",
        "#ff00ff",
        "#ffff00",
    ]
    canvas = tkinter.Canvas(
        root,
        width=SQUARE_SIZE * SQUARES_PER_ROW,
        height=int(len(colors) / SQUARES_PER_ROW + 0.5) * SQUARE_SIZE,
    )
    canvas.pack()

    for i, color in enumerate(colors):
        y, x = (n * SQUARE_SIZE for n in divmod(i, SQUARES_PER_ROW))
        canvas.create_polygon(
            x,
            y,
            x + SQUARE_SIZE,
            y,
            x + SQUARE_SIZE,
            y + SQUARE_SIZE,
            x,
            y + SQUARE_SIZE,
            fill=color,
        )

    root.mainloop()


if __name__ == "__main__":
    main()
Ansonsten schliesse ich mich NPC an: JPEG ist ein verlustbehaftetes Grafikformat das man nicht für diese Art von Grafiken verwenden sollte. PNG wäre beispielsweise geeignet die Pixelwerte 1:1 zu speichern.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
bas_oldy
User
Beiträge: 16
Registriert: Donnerstag 23. August 2018, 20:09

Hallo NPC und Blackjack,

vielen Dank für eure Antworten.

Für NPC: das Ganze ist entstanden, weil ich die Farbwerte auf einem Foto ermitteln wollte und dabei den Eindruck hatte, dass das Ergebnis nicht richtig war. Ich habe deshalb ein "Foto" mit bekannten Farben erstellt und versucht es zu analysieren. Das Bildschirmfoto habe ich mit der auf dem MacBook vorhandenen App "Bildschirmfoto" gemacht.

Für Blackjack: schönes Python werde ich in meinem Alter (75) nicht mehr lernen, sorry. Mir reicht es, wenn ein Code das tut was er soll. Hier tut er´s nicht. Auch wenn ich deinen Code und PNG statt JPEG verwende, wird das Ergebnis der Analyse nicht richtig.

Nochmal vielen Dank

bas_oldy
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der mac beherrscht Farbprofile. Er korrigiert die Darstellung von Farben abhaengig von einem verwandten Farbprofil. Und das ist der Effekt, den du da beobachtest. Wenn du das nicht mehr haben willst, kannst du das wahrscheinlich irgendwo abschalten in den System-Einstellungen. Andere Dinge moegen dann aber auch etwas komisch aussehen.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Wobei man Bedenken sollte das Macs dies tun um sich dem Monitor anzupassen, der ebenfalls Farben nicht zwangsläufig akkurat darstellt. Die Farben die du also vom Bildschirmfoto ermittelt hast, entsprechen sicherlich nicht exakt dem was im Auge des Betrachters tatsächlich ankommt.

Deswegen sind Monitoren für den professionellen Bereich auch schnell relativ teuer und man würde diese auch vor Gebrauch kalibrieren um sicherzustellen dass Farben möglichst korrekt dargestellt werden. Auf der anderen Seite muss man Bedenken dass die allermeisten dies nicht tun in diese Einschränkung im Design mit einbeziehen.
bas_oldy
User
Beiträge: 16
Registriert: Donnerstag 23. August 2018, 20:09

Hallo deets und DasIch,

vielen Dank für eure Hinweise. Sie waren hilfreich. Wenn ich das Bildschirmfoto auf einem Windows-PC erstelle und als .png-Datei speichere werden bei der Analyse genau die zuvor verwendeten Farben gefunden. Mein Problem ist also Mac-spezifisch. Die Sache ist damit für mich erledigt.

Danke!
Antworten