def from_Image(self, im, translate=False): """Load from a PIL Image instance If the input image is 24-bit or 32-bit, the colors will be looked up in the current palette. If the input image is 8-bit, indices will simply be copied from the input image. To properly translate colors between palettes, set the `translate` parameter.""" pixels = im.tobytes() width, height = im.size xoff, yoff = (width // 2)-1, height-5 if im.mode == "RGB": pixels = join([six.int2byte(self.palette.match(unpack('BBB', \ pixels[i*3:(i+1)*3]))) for i in range(width*height)]) self.from_raw(pixels, width, height, xoff, yoff, self.palette) elif im.mode == "RGBA": pixels = [unpack('BBBB', pixels[i*4:(i+1)*4]) for i in range(width*height)] pixels = [self.palette.match(i[0:3]) if i[3] > 0 else None for i in pixels] self.from_pixels(pixels, width, height, xoff, yoff) elif im.mode == 'P': srcpal = im.palette.tobytes() if im.palette.mode == "RGB": palsize = 3 elif im.palette.mode == "RGBA": palsize = 4 else: raise TypeError("palette mode must be 'RGB' or 'RGBA'") if translate: R = [c for c in six.iterbytes(srcpal[0::palsize])] G = [c for c in six.iterbytes(srcpal[1::palsize])] B = [c for c in six.iterbytes(srcpal[2::palsize])] srcpal = zip(R, G, B) lexicon = [six.int2byte(self.palette.match(c)) for c in srcpal] pixels = join([lexicon[b] for b in six.iterbytes(pixels)]) else: # Simply copy pixels. However, make sure to translate # all colors matching the transparency color to the # right index. This is necessary because programs # aren't consistent in choice of position for the # transparent entry. packed_color = pack("BBB", *self.palette.tran_color) ri = 0 while ri != -1: ri = srcpal.find(packed_color, ri+palsize) if not ri % palsize and ri//palsize != self.palette.tran_index: pixels = pixels.replace(six.int2byte(ri//palsize), six.int2byte(self.palette.tran_index)) self.from_raw(pixels, width, height, xoff, yoff, self.palette) else: raise TypeError("image mode must be 'P', 'RGB', or 'RGBA'")
def from_raw(self, data, width, height, x_offset=0, y_offset=0, pal=None): """Load a raw 8-bpp image, converting to the Doom picture format (used by all graphics except flats)""" pal = pal or omg.palette.default pixels = [ i if i != pal.tran_index else None for i in six.iterbytes(data) ] self.from_pixels(pixels, width, height, x_offset, y_offset)
def from_Image(self, im, translate=False): """Load from a PIL Image instance If the input image is 24-bit or 32-bit, the colors will be looked up in the current palette. If the input image is 8-bit, indices will simply be copied from the input image. To properly translate colors between palettes, set the `translate` parameter.""" pixels = im.tobytes() width, height = im.size xoff, yoff = (width // 2) - 1, height - 5 if im.mode == "RGB": pixels = join([six.int2byte(self.palette.match(unpack('BBB', \ pixels[i*3:(i+1)*3]))) for i in range(width*height)]) self.from_raw(pixels, width, height, xoff, yoff, self.palette) elif im.mode == "RGBA": pixels = [ unpack('BBBB', pixels[i * 4:(i + 1) * 4]) for i in range(width * height) ] pixels = [ self.palette.match(i[0:3]) if i[3] > 0 else None for i in pixels ] self.from_pixels(pixels, width, height, xoff, yoff) elif im.mode == 'P': srcpal = im.palette.tobytes() if im.palette.mode == "RGB": palsize = 3 elif im.palette.mode == "RGBA": palsize = 4 else: raise TypeError("palette mode must be 'RGB' or 'RGBA'") if translate: R = [c for c in six.iterbytes(srcpal[0::palsize])] G = [c for c in six.iterbytes(srcpal[1::palsize])] B = [c for c in six.iterbytes(srcpal[2::palsize])] srcpal = zip(R, G, B) lexicon = [six.int2byte(self.palette.match(c)) for c in srcpal] pixels = join([lexicon[b] for b in six.iterbytes(pixels)]) else: # Simply copy pixels. However, make sure to translate # all colors matching the transparency color to the # right index. This is necessary because programs # aren't consistent in choice of position for the # transparent entry. packed_color = pack("BBB", *self.palette.tran_color) ri = 0 while ri != -1: ri = srcpal.find(packed_color, ri + palsize) if not ri % palsize and ri // palsize != self.palette.tran_index: pixels = pixels.replace( six.int2byte(ri // palsize), six.int2byte(self.palette.tran_index)) self.from_raw(pixels, width, height, xoff, yoff, self.palette) else: raise TypeError("image mode must be 'P', 'RGB', or 'RGBA'")
def from_raw(self, data, width, height, x_offset=0, y_offset=0, pal=None): """Load a raw 8-bpp image, converting to the Doom picture format (used by all graphics except flats)""" pal = pal or omg.palette.default pixels = [i if i != pal.tran_index else None for i in six.iterbytes(data)] self.from_pixels(pixels, width, height, x_offset, y_offset)