Frage

Gibt es eine Möglichkeit einzelne Pixelwerte für Bilddaten in Pyglet zu setzen?

Ich denke, es kann auch durch Einstellen des OpenGL-Rendering-Modus Punkte erfolgen, also wenn jemand Einsicht auf diese hat, bitte auch teilen.

War es hilfreich?

Lösung

Im Folgenden ist rein von einem OpenGL Standpunkt, ich weiß nicht von irgendwelchen Pyglet Tricks für diese.

Es gibt immer glDrawPixels , oder Sie könnten ein verwenden OpenGL-Textur, die die gleiche Auflösung wie Ihr Fenster ist (am besten, wenn Sie verwenden können, nicht Leistung von zwei Texturgrößen), die Textur auf einen Quad, die das gesamte Fenster einnimmt.

und dann map

Letzteres Ich denke, ist die schnellste Lösung, wenn Sie nicht zu ändern Pixel auf jeder Aktualisierung, da alle Daten bereits auf der Karte.

können Sie behalten eine „lokale“ (in CPU-Speicher) Cache der Texturdaten für eine einfache Modifikation und Wieder Upload. Oder für Bonuspunkte, können Sie die Texturdaten direkt via OpenCL ändern;)

Andere Tipps

Die Lösung, die die am besten geeignet ich erscheinen am Ende ist die ImageData Klasse zu verwenden, die mit jedem kommt AbstractImage Unterklasse.

Imagedata Array Retrieval

Die ImageData Klasse repräsentiert ein Bild als ein Array von Bytes, oder genauer gesagt ein String von denen jedes Zeichen eines in dem gewünschten Farbkoordinatenraum darstellt.

Um diese Byte-Darstellung eines gegebenen image zu erhalten, würden Sie rufen

image_data = image.get_image_data()
width = image_data.width
data = image_data.get_data('RGB', 3*width)

Der zweite Parameter wir sind vorbei hier get_data ist die Anzahl von Bytes, erwarten wir für jede Zeile des Bildes zu erhalten. Weil wir alle Komponenten R, G und B für jedes einzelne Pixel haben wollen, würden wir 3 mal wie die Breite des Bildes haben. Wenn wir nur in interessiert wäre, sagen wir, die Intensität für jedes Pixel, würden wir die Parameter ('I', image.width) passieren. Hier einige offizielle Dokumentation .

Um die Werte nur für die sehr Pixel erhalten Sie interessiert sind, z.B. die man bei (x,y), möchten Sie vielleicht etw wie dies tun:

pos = (width*y + x) * 3  
rgb = map(ord, data[pos:pos+3])

Statt die ImageData für das gesamte Bild Abrufen und Kommissionierung die Werte des gewünschten Pixel danach können Sie auch get_image_data() für eine bestimmte Region , also 1x1 pixel an der gewünschten Position:

image_data = image.get_region(x,y,1,1).get_image_data()

Das ist die Art und Weise, wie es gemacht wird, ist this Google Gruppen Post , wo Sie auch die nützlichen Informationen finden, dass es effizienter zu sein scheint auf Ihre Bilddaten als RGBA statt RGB zu erhalten.

Einstellung einzelne Pixel

Nun, um endlich Frage zu beantworten, gibt es auch eine Setter-Methode für die Bild Byte Daten von Imagedata, set_data , die um nur in die andere Richtung funktioniert.

image_data.set_data('RGB', image.width*3, data)

Das funktioniert wahrscheinlich für Regionen, auch, aber ich habe nicht versucht. Falls Sie auf Set-Byte-Daten, dass Sie in einem Integer-Array gespeichert sind, Pass ''.join(map(chr, data)). Ich weiß nicht, ob es einen Weg gibt, numerische Werte zu setzen.

Hope dies jemand hilft auf diese ganz alte Frage zu stolpern, die noch ein prominentes Google-Ergebnis für bestimmte Suchbegriffe sein passiert.

Sie können eine Charge mit batch = pyglet.graphics.Batch() einrichten und dann Eckpunkten auf die Batch-Verarbeitung von batch.add(npts, gl_type, group, pixel_data, color_data) Aufruf, wo npts ist die ganze Zahl angibt, wie viele Punkte Sie werden als Tupel in pixel_data werden die Auflistung und gl_type in Ihrem Fall ist pyglet.gl. GL_POINTS. batch.draw() zieht dann alle Ecken, die Sie Ihre Batch hinzugefügt haben. Das Beispiel unten zieht eine Linie von Vertices Zugabe (d.h. GL_POINTS) zu den Charge bei jedem Aufruf von on_draw ():

import pyglet

COLOR = (0,255,0)
FRAMERATE = 1.0/60
(x,y) = (50,50)
window = pyglet.window.Window()
batch = pyglet.graphics.Batch()

# the vertex_list will keep a handle on all the vertices we add to the batch
vertex_list = [batch.add(1, pyglet.gl.GL_POINTS, None,('v2i', (x,y)),('c3B', COLOR))]

@window.event
def on_draw():
   window.clear()

   # the next vertex will use the vertices of the vertex currently at the end of the current vertex_list
   (x,y) = vertex_list[-1].vertices 
   vertex_list.append(batch.add(1, pyglet.gl.GL_POINTS, None,('v2i', (x+1,y+1)),('c3B', COLOR)))       
   batch.draw()

pyglet.clock.schedule_interval(lambda dt: None, FRAMERATE) 
pyglet.app.run()

Es gibt wahrscheinlich eine effizientere Art und Weise Linien zeichnen als die Art und Weise oben, aber auf diese Weise gibt Ihnen eine gute Vorstellung davon, wie die Chargen funktionieren. Schauen Sie sich die Dokumentation für mehr hier.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top