def loader(queue, settings): from pyglet.image import ImageData from PIL import Image, ImageOps import random, glob, time displayed = set() last_scan = time.time() files = glob.glob("{}/*jpg".format(settings['originals'])) new = sorted(list(set(files) - displayed)) while 1: if last_scan + 15 < time.time(): last_scan = time.time() files = glob.glob("{}/*jpg".format(settings['originals'])) new = sorted(list(set(files) - displayed))[15:] if new: filename = random.choice(new) displayed.add(filename) else: filename = random.choice(files) image = Image.open(filename) image = image.transpose(Image.FLIP_TOP_BOTTOM) image.thumbnail(settings['large_size'], Image.ANTIALIAS) image = ImageOps.expand(image, border=32, fill=(255, 255, 255)) w, h = image.size image = image.convert() image = ImageData(w, h, image.mode, image.tostring()) queue.put(image)
def show(self, frame): """ Show an array of pixels on the window. Args: frame (numpy.ndarray): the frame to show on the window Returns: None """ # check that the frame has the correct dimensions if len(frame.shape) != 3: raise ValueError('frame should have shape with only 3 dimensions') # open the window if it isn't open already if not self.is_open: self.open() # prepare the window for the next frame self._window.clear() self._window.switch_to() self._window.dispatch_events() # create an image data object image = ImageData(frame.shape[1], frame.shape[0], 'RGB', frame.tobytes(), pitch=frame.shape[1] * -3) # send the image to the window image.blit(0, 0, width=self._window.width, height=self._window.height) self._window.flip()
def generatePygletGrating(grating, height=1280, width=1024, L=50, theta=0, title=""): canvas_size = (width+2*L, height+2*L) # width, height map_dir = os.path.join("map", "{prefix}_{p1}_{p2}_{p3}_{p4}".format( prefix=title, p1=height, p2=width, p3=int(L), p4=int(theta/np.pi*180))) if os.path.isfile(map_dir): logger.debug("reading map: "+title) with open(map_dir, 'rb') as mapfile: data = mapfile.read() unit_map = ImageData(width=canvas_size[0], height=canvas_size[1], data=data, format='RGBA', pitch=canvas_size[0]*4) return unit_map else: logger.debug("generating map: "+title) datamap = np.zeros((canvas_size[1], canvas_size[0], 4), dtype=np.int8) for x in range(canvas_size[0]): for y in range(canvas_size[1]): datamap[y, x] = grating(x, y) with open(map_dir, "wb") as mapfile: mapfile.write(datamap.tobytes()) logger.debug("generating map: "+title) return ImageData(width=canvas_size[0], height=canvas_size[1], data=datamap.tobytes(), format='RGBA', pitch=canvas_size[0]*4)
def draw(self): data = ImageData( *self.__image.size, 'RGBA', self.__image.tobytes(), pitch=-self.__image.size[0]*4 ) data.blit(0, 0)
def imshow(self, arr, caption): height, width, _ = arr.shape if self.window is None: self.width = width self.height = height self.isopen = True self.window = Window(width=width, height=height, display=self.display, vsync=False, resizable=True) assert len(arr.shape) == 3 image = ImageData(width, height, 'RGB', arr.tobytes(), pitch=-3 * width) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) texture = image.get_texture() texture.width = self.width texture.height = self.height self.window.clear() self.window.switch_to() self.window.dispatch_events() texture.blit(0, 0) self.window.flip() self.window.set_caption(caption)
def get_image(self): # We need to pass a negative stride here since the image # will be upside-down otherwise. img = ImageData(self.width, self.height, 'RGBA', str(self.array), -self.stride) img.anchor_x = self.anchor_x img.anchor_y = self.anchor_y return img
def render(self, img_array): from pyglet.image import ImageData from pyglet.gl import glClearColor glClearColor(1,1,1,1) img_array = np.ascontiguousarray(img_array[::-1, :]) img_c_array = img_array.ctypes.data_as(ctypes.POINTER(ctypes.c_float * img_array.size)) img_data = ImageData(img_array.shape[0], img_array.shape[1], 'L', img_c_array) self.window.clear() self.window.switch_to() self.window.dispatch_events() img_data.blit(0, 0) self.window.flip()
def _render(self, mode='human', close=False): import pyglet from pyglet.image import ImageData from pyglet.gl import glPushMatrix, glPopMatrix, glScalef, glTranslatef if mode == 'rgb_array': return self.img if close: if self.window: self.window.close() return if self.window is None: # For displaying text self.textLabel = pyglet.text.Label(font_name="Arial", font_size=14, x=5, y=WINDOW_SIZE - 19) self.window = pyglet.window.Window(width=WINDOW_SIZE, height=WINDOW_SIZE) self.window.clear() self.window.switch_to() self.window.dispatch_events() if self.stateData is None: return # Draw the image to the rendering window width = self.img.shape[0] height = self.img.shape[1] imgData = ImageData( width, height, 'RGB', self.img.tobytes(), pitch=width * 3, ) glPushMatrix() glTranslatef(0, WINDOW_SIZE, 0) glScalef(1, -1, 1) imgData.blit(0, 0, 0, WINDOW_SIZE, WINDOW_SIZE) glPopMatrix() # Display position/state information pos = self.stateData['position'] self.textLabel.text = "(%.2f, %.2f, %.2f)" % (pos[0], pos[1], pos[2]) self.textLabel.draw() self.window.flip()
def __init__(self, **kwargs): kwargs.setdefault('filename', os.path.join('..', 'photoo', 'photo1.jpg')) if kwargs.get('filename') is None: raise Exception('No filename given to MTScatterImage') kwargs.setdefault('loader', None) super(ImageScatter, self).__init__(**kwargs) self.touch_positions = {} self.pim = Image.open(kwargs.get('filename')) self.contrast_enh = ImageEnhance.Contrast(self.pim) self.pim = self.contrast_enh.enhance(1.0) self.bright_enh = ImageEnhance.Brightness(self.pim) self.pim = self.bright_enh.enhance(1.0) self.color_enh = ImageEnhance.Color(self.pim) self.pim = self.color_enh.enhance(1.0) self.sharp_enh = ImageEnhance.Sharpness(self.pim) self.pim = self.sharp_enh.enhance(1.0) self.bdata = self.pim.tostring() self.img = ImageData(self.pim.size[0], self.pim.size[1], 'RGB', self.bdata, pitch=-self.pim.size[0] * 3) self.image = pyglet.sprite.Sprite(self.img) self.width = self.pim.size[0] self.height = self.pim.size[1]
def _get_pyglet_ImageData_from_source_at_index(self, sourceRef, index): imageRef = c_void_p(quartz.CGImageSourceCreateImageAtIndex(sourceRef, index, None)) # Regardless of the internal format of the image (L, LA, RGB, RGBA, etc) # we just automatically convert everything to an RGBA format. format = 'RGBA' rgbColorSpace = c_void_p(quartz.CGColorSpaceCreateDeviceRGB()) bitsPerComponent = 8 width = quartz.CGImageGetWidth(imageRef) height = quartz.CGImageGetHeight(imageRef) bytesPerRow = 4 * width # Create a buffer to store the RGBA formatted data. bufferSize = height * bytesPerRow buffer = (c_ubyte * bufferSize)() # Create a bitmap context for the RGBA formatted data. # Note that premultiplied alpha is required: # http://developer.apple.com/library/mac/#qa/qa1037/_index.html bitmap = c_void_p(quartz.CGBitmapContextCreate(buffer, width, height, bitsPerComponent, bytesPerRow, rgbColorSpace, kCGImageAlphaPremultipliedLast)) # Write the image data into the bitmap. quartz.CGContextDrawImage(bitmap, NSMakeRect(0,0,width,height), imageRef) quartz.CGImageRelease(imageRef) quartz.CGContextRelease(bitmap) quartz.CGColorSpaceRelease(rgbColorSpace) pitch = bytesPerRow return ImageData(width, height, format, buffer, -pitch)
def __create_cocos_node(self, size, color): im = Image.new('RGBA', (int(size), int(size)), (255, 255, 255, 0)) draw = ImageDraw.Draw(im) draw.ellipse((1, 1, im.size[0] - 1, im.size[1] - 1), fill=color) data = ImageData(*im.size, 'RGBA', im.tobytes(), pitch=-im.size[0] * 4) return Sprite(data)
def decode(self, filename, file): if not file: file = open(filename, 'rb') try: reader = pypng.Reader(file=file) width, height, pixels, metadata = reader.asDirect() except Exception as e: raise ImageDecodeException('PyPNG cannot read %r: %s' % (filename or file, e)) if metadata['greyscale']: if metadata['alpha']: fmt = 'LA' else: fmt = 'L' else: if metadata['alpha']: fmt = 'RGBA' else: fmt = 'RGB' pitch = len(fmt) * width pixels = array.array('BH'[metadata['bitdepth'] > 8], itertools.chain(*pixels)) return ImageData(width, height, fmt, pixels.tobytes(), -pitch)
def decode_animation(self, file, filename): header, frames, layers, pitch = self._parse_file(file, filename) animation_frames = [] for frame in frames: pixel_data = frame.get_pixel_array(layers=layers) image = ImageData(header.width, header.height, 'RGBA', pixel_data, -pitch) animation_frames.append(AnimationFrame(image, frame.duration/1000.0)) return Animation(animation_frames)
def changeSharpness(self, value): self.pim = self.sharp_enh.enhance(value) self.bdata = self.pim.tostring() self.img = ImageData(self.pim.size[0], self.pim.size[1], 'RGB', self.bdata, pitch=-self.pim.size[0] * 3) self.image = pyglet.sprite.Sprite(self.img)
def update(self, dt): received = 0 img_buf = b"" size_data = self.sock.recv(4) size = struct.unpack(">I", size_data)[0] while True: data = self.sock.recv(size - received) received += len(data) img_buf += data if size <= received: break img = Image.open(io.BytesIO(img_buf)) #img = img.transpose(Image.FLIP_TOP_BOTTOM) img = img.transpose(Image.FLIP_LEFT_RIGHT) img = ImageData(self.width, self.height, "RGB", img.tobytes("raw", "RGB")) img.blit(0, 0)
def decode_8bit(bits, palette, width, height, pitch, pitch_sign): rgb_pitch = pitch * 3 buffer = (ctypes.c_ubyte * (height * rgb_pitch))() i = 0 for row in bits: for index in row: rgb = palette[index] buffer[i] = rgb.rgbRed buffer[i + 1] = rgb.rgbGreen buffer[i + 2] = rgb.rgbBlue i += 3 return ImageData(width, height, 'RGB', buffer, pitch_sign * rgb_pitch)
def decode_4bit(bits, palette, width, height, pitch, pitch_sign): rgb_pitch = (((pitch << 1) + 1) & ~0x1) * 3 buffer = (ctypes.c_ubyte * (height * rgb_pitch))() i = 0 for row in bits: for packed in row: for index in ((packed & 0xf0) >> 4, packed & 0xf): rgb = palette[index] buffer[i] = rgb.rgbRed buffer[i + 1] = rgb.rgbGreen buffer[i + 2] = rgb.rgbBlue i += 3 return ImageData(width, height, 'RGB', buffer, pitch_sign * rgb_pitch)
def decode_1bit(bits, palette, width, height, pitch, pitch_sign): rgb_pitch = (((pitch << 3) + 7) & ~0x7) * 3 buffer = (ctypes.c_ubyte * (height * rgb_pitch))() i = 0 for row in bits: for packed in row: for _ in range(8): rgb = palette[(packed & 0x80) >> 7] buffer[i] = rgb.rgbRed buffer[i + 1] = rgb.rgbGreen buffer[i + 2] = rgb.rgbBlue i += 3 packed <<= 1 return ImageData(width, height, 'RGB', buffer, pitch_sign * rgb_pitch)
def create_image(self, width, height): data = b'' for i in range(width * height): pos_x = i % width pos_y = i // width if pos_x / width <= 0.08: data += bytes(self.light_color) elif pos_y / height <= 0.08: data += bytes(self.dark_color) elif pos_y / height >= 0.92: data += bytes(self.light_color) elif pos_x / width >= 0.92: data += bytes(self.dark_color) else: data += bytes(self.color) return ImageData(width, height, 'RGBA', data)
def get_image_data(image): """ Retrieve image data from a PIL Image so it can be loaded into a Pyglet image. Returns the data wrapped in a Pyglet ImageData object. """ image = image.transpose(Image.FLIP_TOP_BOTTOM) # Convert bitmap and palette images to component if image.mode in ('1', 'P'): image = image.convert() if image.mode not in ('L', 'LA', 'RGB', 'RGBA'): raise ImageDecodeException('Unsupported mode "%s"' % image.mode) width, height = image.size return ImageData(width, height, image.mode, image.tostring())
def PILImageToPyglet(image): "Given a PIL image, return a pyglet image" import PIL.Image as Image from pyglet.image import ImageData image = image.transpose(Image.FLIP_TOP_BOTTOM) # Convert bitmap and palette images to component if image.mode in ('1', 'P'): image = image.convert() if image.mode not in ('L', 'LA', 'RGB', 'RGBA'): raise ImageDecodeException('Unsupported mode "%s"' % image.mode) type = GL_UNSIGNED_BYTE width, height = image.size return ImageData(width, height, image.mode, image.tostring())
def decode_bitfields(bits, r_mask, g_mask, b_mask, width, height, pitch, pitch_sign): r_shift1, r_shift2 = get_shift(r_mask) g_shift1, g_shift2 = get_shift(g_mask) b_shift1, b_shift2 = get_shift(b_mask) rgb_pitch = 3 * len(bits[0]) buffer = (ctypes.c_ubyte * (height * rgb_pitch))() i = 0 for row in bits: for packed in row: buffer[i] = (packed & r_mask) >> r_shift1 << r_shift2 buffer[i+1] = (packed & g_mask) >> g_shift1 << g_shift2 buffer[i+2] = (packed & b_mask) >> b_shift1 << b_shift2 i += 3 return ImageData(width, height, 'RGB', buffer, pitch_sign * rgb_pitch)
def decode_32bit_rgb(bits, palette, width, height, pitch, pitch_sign): buffer = (ctypes.c_ubyte * (height * pitch))() ctypes.memmove(buffer, bits, len(buffer)) return ImageData(width, height, 'BGRA', buffer, pitch_sign * pitch)
from numpy import zeros, arange from random import shuffle from pyglet.image import ImageData width = 1280 height = 720 frame = 300 color_type = 'uint8' color_max = 255 area = width * height board = zeros(area, color_type) idx = arange(area) shuffle(idx) for i in range(frame): board[idx[i::frame]] = color_max image = ImageData(width, height, 'I', board.tobytes()) image.save('{}.png'.format(i)) # C:\AviUtlPack\3rdparty\ffmpeg.exe -framerate 60 -i %d.png -c:v libx264 -preset ultrafast -qp 0 scn.mp4
def apply_actor(sprites, frame): sprite = sprites[frame.image_n] return ImageData(sprite.width, sprite.height, 'RGBA', ''.join(sprite.data))
def imshow(self, data, *, keepdims=True): """Show the monochrome, RGB or RGBA image data, or a matplotlib Figure. Parameters ---------- data : numpy.ndarray, or matplotlib.figure.Figure The data to display in the viewer. * If `data` is a matplotlib Figure, that has already been composed elsewhere, then it gets rendered into a 3d RGBA array and displayed as color image. * If `data` is a numpy array, then it must either be a 2d or a 3d array for a grayscale or color image, respectively. In the color image case the last dim of the array must have size `3` for an RGB image or `4` for and RGBA image (RGB with an alpha channel). keepdims : bool, default=True Whether to preserve the current dimensions of the viewer, or resize it to fit the width and height of the current image. Details ------- To prevent memory leaks it is advisable to close the figure afterwards, using `plt.close(fig)`. However, creating a new figure and then closing it appears to incur excessive overhead. One possible workaround is to create a figure and axes only once, and, when updating it, recreate its contents on the axes before and clear them after any call to `.imshow`. In general matplotlib is not optimized for live redrawing, but lowering `figsize` and `dpi` may improve fps. """ if not self.isopen: return False # use the `agg` backend directly to create RGBA arrays from figures # https://matplotlib.org/stable/gallery/user_interfaces/canvasagg.html if isinstance(data, Figure): # assume all necessary plotting and artistry has been done canvas = FigureCanvasAgg(data) # XXX does not seem to leak mem # render into a buffer and convert to numpy array canvas.draw() data = np.array(canvas.buffer_rgba()) if not isinstance(data, np.ndarray): raise TypeError(f'`data` must be either a numpy array or a' f' matplotlib `Figure`. Got `{type(data)}`.') # figure out the image format if not data.dtype == np.uint8: raise TypeError(f'`data` must be `np.unit8`. Got `{data.dtype}`.') height, width, *channels = data.shape if not channels: # grayscale image format = 'I' elif len(channels) == 1: # color image optionally with alpha channel assert channels[0] in (3, 4) format = 'RGBA' if channels[0] == 4 else 'RGB' else: raise TypeError(f'`data` is not an image `{data.shape}`.') # ensure the current window's gl context before manipulating textures self.switch_to() # convert image data to gl texture texture = ImageData(width, height, format, data.tobytes(), pitch=-width * len(format)).get_texture() # resize if instructed or on the first call to `.imshow` if not hasattr(self, 'texture') or not keepdims: sw, sh = self.scale self.set_size(texture.width * sw, texture.height * sh) self.texture = texture # handle events and draw the data return self.render()
def __create_image(self, size, color): im = Image.new('RGBA', (size, size), (255, 255, 255, 0)) draw = ImageDraw.Draw(im) draw.ellipse((1, 1, im.size[0]-1, im.size[1]-1), fill=color) return ImageData(*im.size, 'RGBA', im.tobytes(), pitch=-im.size[0]*4)
async def render(self, observation): render_data = observation.observation.render_data map_size = render_data.map.size map_data = render_data.map.data minimap_size = render_data.minimap.size minimap_data = render_data.minimap.data map_width, map_height = map_size.x, map_size.y map_pitch = -map_width * 3 minimap_width, minimap_height = minimap_size.x, minimap_size.y minimap_pitch = -minimap_width * 3 if not self._window: from pyglet.window import Window from pyglet.image import ImageData from pyglet.text import Label self._window = Window(width=map_width, height=map_height) self._window.on_mouse_press = self._on_mouse_press self._window.on_mouse_release = self._on_mouse_release self._window.on_mouse_drag = self._on_mouse_drag self._map_image = ImageData(map_width, map_height, 'RGB', map_data, map_pitch) self._minimap_image = ImageData(minimap_width, minimap_height, 'RGB', minimap_data, minimap_pitch) self._text_supply = Label('', font_name='Arial', font_size=16, anchor_x='right', anchor_y='top', x=self._map_size[0] - 10, y=self._map_size[1] - 10, color=(200, 200, 200, 255)) self._text_vespene = Label('', font_name='Arial', font_size=16, anchor_x='right', anchor_y='top', x=self._map_size[0] - 130, y=self._map_size[1] - 10, color=(28, 160, 16, 255)) self._text_minerals = Label('', font_name='Arial', font_size=16, anchor_x='right', anchor_y='top', x=self._map_size[0] - 200, y=self._map_size[1] - 10, color=(68, 140, 255, 255)) self._text_score = Label('', font_name='Arial', font_size=16, anchor_x='left', anchor_y='top', x=10, y=self._map_size[1] - 10, color=(219, 30, 30, 255)) self._text_time = Label('', font_name='Arial', font_size=16, anchor_x='right', anchor_y='bottom', x=self._minimap_size[0] - 10, y=self._minimap_size[1] + 10, color=(255, 255, 255, 255)) else: self._map_image.set_data('RGB', map_pitch, map_data) self._minimap_image.set_data('RGB', minimap_pitch, minimap_data) self._text_time.text = str( datetime.timedelta( seconds=(observation.observation.game_loop * 0.725) // 16)) if observation.observation.HasField('player_common'): self._text_supply.text = "{} / {}".format( observation.observation.player_common.food_used, observation.observation.player_common.food_cap) self._text_vespene.text = str( observation.observation.player_common.vespene) self._text_minerals.text = str( observation.observation.player_common.minerals) if observation.observation.HasField('score'): self._text_score.text = "{} score: {}".format( score_pb._SCORE_SCORETYPE.values_by_number[ observation.observation.score.score_type].name, observation.observation.score.score) await self._update_window() if self._client.in_game and (not observation.player_result ) and self._mouse_x and self._mouse_y: await self._client.move_camera_spatial( Point2((self._mouse_x, self._minimap_size[0] - self._mouse_y))) self._mouse_x, self._mouse_y = None, None
class Renderer(object): def __init__(self, client, map_size, minimap_size) -> None: self._client = client self._window = None self._map_size = map_size self._map_image = None self._minimap_size = minimap_size self._minimap_image = None self._mouse_x, self._mouse_y = None, None self._text_supply = None self._text_vespene = None self._text_minerals = None self._text_score = None self._text_time = None async def render(self, observation): render_data = observation.observation.render_data map_size = render_data.map.size map_data = render_data.map.data minimap_size = render_data.minimap.size minimap_data = render_data.minimap.data map_width, map_height = map_size.x, map_size.y map_pitch = -map_width * 3 minimap_width, minimap_height = minimap_size.x, minimap_size.y minimap_pitch = -minimap_width * 3 if not self._window: from pyglet.window import Window from pyglet.image import ImageData from pyglet.text import Label self._window = Window(width=map_width, height=map_height) self._window.on_mouse_press = self._on_mouse_press self._window.on_mouse_release = self._on_mouse_release self._window.on_mouse_drag = self._on_mouse_drag self._map_image = ImageData(map_width, map_height, 'RGB', map_data, map_pitch) self._minimap_image = ImageData(minimap_width, minimap_height, 'RGB', minimap_data, minimap_pitch) self._text_supply = Label('', font_name='Arial', font_size=16, anchor_x='right', anchor_y='top', x=self._map_size[0] - 10, y=self._map_size[1] - 10, color=(200, 200, 200, 255)) self._text_vespene = Label('', font_name='Arial', font_size=16, anchor_x='right', anchor_y='top', x=self._map_size[0] - 130, y=self._map_size[1] - 10, color=(28, 160, 16, 255)) self._text_minerals = Label('', font_name='Arial', font_size=16, anchor_x='right', anchor_y='top', x=self._map_size[0] - 200, y=self._map_size[1] - 10, color=(68, 140, 255, 255)) self._text_score = Label('', font_name='Arial', font_size=16, anchor_x='left', anchor_y='top', x=10, y=self._map_size[1] - 10, color=(219, 30, 30, 255)) self._text_time = Label('', font_name='Arial', font_size=16, anchor_x='right', anchor_y='bottom', x=self._minimap_size[0] - 10, y=self._minimap_size[1] + 10, color=(255, 255, 255, 255)) else: self._map_image.set_data('RGB', map_pitch, map_data) self._minimap_image.set_data('RGB', minimap_pitch, minimap_data) self._text_time.text = str( datetime.timedelta( seconds=(observation.observation.game_loop * 0.725) // 16)) if observation.observation.HasField('player_common'): self._text_supply.text = "{} / {}".format( observation.observation.player_common.food_used, observation.observation.player_common.food_cap) self._text_vespene.text = str( observation.observation.player_common.vespene) self._text_minerals.text = str( observation.observation.player_common.minerals) if observation.observation.HasField('score'): self._text_score.text = "{} score: {}".format( score_pb._SCORE_SCORETYPE.values_by_number[ observation.observation.score.score_type].name, observation.observation.score.score) await self._update_window() if self._client.in_game and (not observation.player_result ) and self._mouse_x and self._mouse_y: await self._client.move_camera_spatial( Point2((self._mouse_x, self._minimap_size[0] - self._mouse_y))) self._mouse_x, self._mouse_y = None, None async def _update_window(self): self._window.switch_to() self._window.dispatch_events() self._window.clear() self._map_image.blit(0, 0) self._minimap_image.blit(0, 0) self._text_time.draw() self._text_score.draw() self._text_minerals.draw() self._text_vespene.draw() self._text_supply.draw() self._window.flip() def _on_mouse_press(self, x, y, button, modifiers): if button != 1: # 1: mouse.LEFT return if x > self._minimap_size[0] or y > self._minimap_size[1]: return self._mouse_x, self._mouse_y = x, y def _on_mouse_release(self, x, y, button, modifiers): if button != 1: # 1: mouse.LEFT return if x > self._minimap_size[0] or y > self._minimap_size[1]: return self._mouse_x, self._mouse_y = x, y def _on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): if not buttons & 1: # 1: mouse.LEFT return if x > self._minimap_size[0] or y > self._minimap_size[1]: return self._mouse_x, self._mouse_y = x, y
def decode(self, file, filename): header, frames, layers, pitch = self._parse_file(file, filename) pixel_data = frames[0].get_pixel_array(layers=layers) return ImageData(header.width, header.height, 'RGBA', pixel_data, -pitch)