Reputation: 23500
I got a strange phenomenon when working with pyglets .save()
function.
When i leave it out of the code the output of the application looks like this:
The black area is the main window object, the gray area is the graph()
class and the green line is modified data of the graph's pixel-data, so the green line is not an overlay or a separate object, it's part of the pixeldata itself.
As soon as i add self.texture.save()
(the gray+green pixel data), the screen goes black (it's just as if self.texture
goes full alpha on me or the pixeldata simply disappears) and the kitten.png
(example code for saving images) file looks like:
(yea it's blank/transparent in case you thought i was trolling...)
#!/usr/bin/python
import pyglet, sys, select
...
class Graph(pyglet.sprite.Sprite):
def __init__(self, color="#C2C2C2", x=None, y=None, plotpoints=[], maxx=None, maxy=None):
self.texture = self.gen_solid_img(width+20, height+20, color)
tmp = self.texture.get_image_data()
data = tmp.get_data('RGBA', tmp.width * 4)
## YXColorMap converts the string-data representing the image
## into a dictionary of map[y][x] = pixeldata
data = YXColorMap(data, tmp.width)
## Now here's where i can do:
## data[y][x] = (255,255,255,255)
## to say, modify x,y pixel to completely white.
## And i do this via plot-points
## (yes, ugly and not mathematically fast, but it works.
for item in plotpoints:
data[item[1]][item[0]] = IntToColor(*item[2])
## MapToString stitches dictionary-obj back
## to a string object that can be used in pyglet.
data = MapToString(data)
## Then we set that data as the texture,
## In theory this should replace the entire texture?
self.texture.set_data('RGBA', tmp.width * 4, data)
## Rendering the image up until this point works fine..
## As soon as i do this however the image goes blank:
## (example copied straight from the pyglet website)
self.texture.save('kitten.png') #even with file=.. it's broken
## This would fix the rendering issue, but not the file on disk:
# Not sure why i would need to re-set the "data" after .save()
# but it will render the green line again instead of nothing.
# self.texture.set_data('RGBA', tmp.width * 4, data)
super(Graph, self).__init__(self.texture, x=x, y=y)
self.x = x
self.y = y
def gen_solid_img(self, width, height, c):
if type(c) == str:
c = c.lstrip("#")
c = max(6-len(c),0)*"0" + c
r = int(c[:2], 16)
g = int(c[2:4], 16)
b = int(c[4:], 16)
a = 0.2*255
elif type(c) == tuple:
r, g, b, a = c
c = (r,g,b,a)
return pyglet.image.SolidColorImagePattern(c).create_image(width, height)
Upvotes: 0
Views: 352
Reputation: 11
I know this is an old post, but it I found it from a Google search, so I hope that this answer can help anyone else looking for a similar thing.
I've had a hack at the code, and here is what I have come up with:
import pyglet
def YXColorMap(data, width, format_length):
YX = [data[i:i+format_length] for i in range(0, len(data), format_length)]
return [YX[i:i+width] for i in range(0, len(YX), width)]
def MapToString(colour_map):
YX = [item for row in colour_map for item in row]
return bytes([b for item in YX for b in item])
class Graph(pyglet.sprite.Sprite):
def __init__(self, color="#C2C2C2", width=640, height=480, x=0, y=0, plotpoints=[], maxx=None, maYX=None):
texture = self.gen_solid_img(width, height, color)
tmp = texture.get_image_data()
data = tmp.get_data('RGBA', tmp.width * 4)
colour_map = YXColorMap(data, tmp.width, 4)
for yP, xP, color in plotpoints:
colour_map[yP][xP] = color
tmp.set_data('RGBA', tmp.width * 4, MapToString(colour_map))
super().__init__(texture)
self.x = x
self.y = y
def save_image(self, fileName):
self._texture.save(fileName)
def gen_solid_img(self, width, height, c):
if type(c) == str:
c = c.lstrip("#")
c = max(6-len(c),0)*"0" + c
r = int(c[:2], 16)
g = int(c[2:4], 16)
b = int(c[4:], 16)
a = int(0.2 * 255)
elif type(c) == tuple:
r, g, b, a = c
c = (r,g,b,a)
return pyglet.image.SolidColorImagePattern(c).create_image(width, height)
if __name__ == '__main__':
plotpoints = [(x+2, x, (0, 0, 255, 255)) for x in range(0, 360)]
window = pyglet.window.Window()
graph = Graph(plotpoints=plotpoints)
def on_draw():
graph.draw()
window.on_draw = on_draw
graph.save_image('kitten.png')
pyglet.app.run()
It should open up a window with a diagonal blue line and save the graph to a file called kitten.png
I think the problem with the code in the question is perhaps a confusion between self.texture
and self._texture
, where self.texture
is a variable assigned by the Graph class, and self._texture
is the texture of the sprite.
Upvotes: 1