p.s. I also get strange behavior in the saved .png. The generated image displays correctly in my window, but the saved file doesn't match, almost like a whole color channel is missing. Seems like
is screwy with the channels.
import pyglet
class MutableImage(object):
FORMAT = 'RGB'
def __init__(self, image):
self.image = image
self.imageData = image.get_data(MutableImage.FORMAT, image.width * len(MutableImage.FORMAT))
self.dataList = list(self.imageData)
def getPixel(self, x, y):
'''Returns tuple of (r, g, b)'''
pixelIdx = x + (y * self.image.width)
byteIdx = pixelIdx * len(MutableImage.FORMAT)
return (
ord(self.dataList[byteIdx]),
ord(self.dataList[byteIdx + 1]),
ord(self.dataList[byteIdx + 2])
)
def setPixel(self, x, y, color):
''' color is tuple of (R, G, B) as integers 0-255 '''
# ignore requests to draw out of bounds
if self.inBounds(x, y):
pixelIdx = x + (y * self.image.width)
byteIdx = pixelIdx * len(MutableImage.FORMAT)
r, g, b = color
self.dataList[byteIdx] = chr(r)
self.dataList[byteIdx + 1] = chr(g)
self.dataList[byteIdx + 2] = chr(b)
def getImage(self):
''' return the current state of data '''
data = ''.join(self.dataList)
self.image.set_data(MutableImage.FORMAT, self.image.width * len(MutableImage.FORMAT), data)
# without hack of saving as file then loading as file, a fraction of left side
# gets redrawn on right side for no apparent reason when we blit the image
self.image.save('hack-around.png')
return pyglet.image.load('hack-around.png')
def inBounds(self, x, y):
if x < self.image.width and y < self.image.height:
return True
return False
def clamp(self, x, y):
if x >= self.image.width:
x = self.image.width - 1
if y >= self.image.height:
y = self.image.height - 1
return (x, y)
def paintRectangle(self, lowerLeftCorner, upperRightCorner, color):
''' coords in (x, y) tuple '''
x1, y1 = lowerLeftCorner
x2, y2 = upperRightCorner
x1, y1 = self.clamp(x1, y1)
x2, y2 = self.clamp(x2, y2)
for x in range(x1, x2 + 1):
for y in range(y1, y2 + 1):
self.setPixel(x, y, color)
def copyRegion(self, src, dest, width, height):
''' src and dest (x, y) tuples of lower left corner of regions '''
pass
def paintImage(self, dest, srcImage):
''' dest specifies lower left corner where to draw the srcImage '''
mutableSrcImage = MutableImage(srcImage)
destX, destY = dest
for x in range(srcImage.width):
for y in range(srcImage.height):
color = mutableSrcImage.getPixel(x, y)
self.setPixel(x + destX, y + destY, color)
def displayWindow(image):
window = pyglet.window.Window(image.width, image.height, caption='image render')
@window.event
def on_draw():
image.blit(0, 0)
pyglet.app.run()
mi = MutableImage(pyglet.image.create(500, 900))
mi.paintRectangle((100, 0), (500, 900), (0, 255, 0))
for x in range(50, 500):
mi.setPixel(x, 850, (255, 0, 0))
for x in range(50, 500):
mi.setPixel(x, 450, (255, 0, 0))
for x in range(50, 500):
mi.setPixel(x, 250, (255, 0, 0))
mi.paintRectangle((0, 0), (100, 100), (0, 255, 255))
mi.paintRectangle((450, 850), (500, 900), (0, 255, 255))
displayWindow(mi.getImage())