def test_getcolor(): palette = ImagePalette.ImagePalette() assert len(palette.palette) == 0 assert len(palette.colors) == 0 test_map = {} for i in range(256): test_map[palette.getcolor((i, i, i))] = i assert len(test_map) == 256 # Colors can be converted between RGB and RGBA rgba_palette = ImagePalette.ImagePalette("RGBA") assert rgba_palette.getcolor((0, 0, 0)) == rgba_palette.getcolor( (0, 0, 0, 255)) assert palette.getcolor((0, 0, 0)) == palette.getcolor((0, 0, 0, 255)) # An error is raised when the palette is full with pytest.raises(ValueError): palette.getcolor((1, 2, 3)) # But not if the image is not using one of the palette entries palette.getcolor((1, 2, 3), image=Image.new("P", (1, 1))) # Test unknown color specifier with pytest.raises(ValueError): palette.getcolor("unknown")
def test__new(self): from PIL import ImagePalette im = hopper("RGB") im_p = hopper("P") blank_p = Image.new("P", (10, 10)) blank_pa = Image.new("PA", (10, 10)) blank_p.palette = None blank_pa.palette = None def _make_new(base_image, im, palette_result=None): new_im = base_image._new(im) self.assertEqual(new_im.mode, im.mode) self.assertEqual(new_im.size, im.size) self.assertEqual(new_im.info, base_image.info) if palette_result is not None: self.assertEqual(new_im.palette.tobytes(), palette_result.tobytes()) else: self.assertIsNone(new_im.palette) _make_new(im, im_p, im_p.palette) _make_new(im_p, im, None) _make_new(im, blank_p, ImagePalette.ImagePalette()) _make_new(im, blank_pa, ImagePalette.ImagePalette())
def test_sanity(): palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3) assert len(palette.colors) == 256 with pytest.raises(ValueError): ImagePalette.ImagePalette("RGB", list(range(256)) * 3, 10)
def _save_anim(self, fname): from PIL import Image anim = next((a for a in self._air if a.code == self._anim)) #60 tick ps = 1/60 s = 1000/60 ms ~= 16ms per frame max_w, max_h = 0, 0 frames = [] for el in anim.animation_elements: if el == air.LOOP_START: print("LOOP START") #TODO:handle animation loop correctly continue frame = self._sff.get_image(el.group_number, el.image_number, self._pal, _type="cmap") p = self._pal if self._pal is not None else self._sff.tmp[ el.group_number][el.image_number].palette.data frame = Image.fromarray(frame).convert('P') if frame.size[0] > max_w: max_w = frame.size[0] if frame.size[1] > max_h: max_h = frame.size[1] frames.extend([frame] * abs(el.time)) from PIL import ImagePalette p = ImagePalette.ImagePalette(mode='RGB', palette=bytearray( p.reshape(-1, order='F'))) base = Image.new("RGB", (max_w, max_h)).convert('P') base.save(fname, save_all=True, duration=16, append_images=frames, loop=0, trasparency=0, palette=p)
def convert_palette_image_pil_palette(self) -> Optional[PILImage.Image]: """ Converts the stored palettized version of the image into a full color RGBA image If a palette image exists, a palette based PIL image will be returned If no palette image exists, None is returned """ if self.image256 is None: return None log.debug("Palette conversion pending") newImage = PILImage.new('P', (self.header.width, self.header.height)) newPalette = ImagePalette.ImagePalette(mode='RGBA') for index, color in enumerate(self.palette.palette_entries): newColorTuple = tuple(color[:3]) newPalette.colors[newColorTuple] = index newPalette.palette[index] = newColorTuple[0] newPalette.palette[index + 256] = newColorTuple[1] newPalette.palette[index + 512] = newColorTuple[2] newPalette.palette[index + 768] = 128 newPalette.dirty = 1 imageData = [] for data in self.image256.image: imageData.append(ord(data)) newImage.putdata(imageData) newImage.palette = newPalette return newImage
def test_getdata(): # Test getheader/getdata against legacy values. # Create a 'P' image with holes in the palette. im = Image._wedge().resize((16, 16), Image.NEAREST) im.putpalette(ImagePalette.ImagePalette("RGB")) im.info = {"background": 0} passed_palette = bytes([255 - i // 3 for i in range(768)]) GifImagePlugin._FORCE_OPTIMIZE = True try: h = GifImagePlugin.getheader(im, passed_palette) d = GifImagePlugin.getdata(im) import pickle # Enable to get target values on pre-refactor version # with open('Tests/images/gif_header_data.pkl', 'wb') as f: # pickle.dump((h, d), f, 1) with open("Tests/images/gif_header_data.pkl", "rb") as f: (h_target, d_target) = pickle.load(f) assert h == h_target assert d == d_target finally: GifImagePlugin._FORCE_OPTIMIZE = False
def map_index_to_paletted_image(size, index_data, colors): """ Creates a paletted image from the given data :param size: an (x,y) tuple :param index_data: a list of indexes of length x*y, corresponding to indexes in the color array :param colors: a list of (r,g,b) or (r,g,b,a) tuples :return: a paletted image with the given pixel data """ if not (0 < len(colors) <= 256): raise ValueError('Number of colors out of bounds') # store the result in a paletted image palette_image = Image.new('P', size) # if there's a transparency channel, it needs to be recorded in img.info if len(colors[0]) > 3: transparency = [0] * 256 transparency[0:len(colors)] = [color[3] for color in colors] palette_image.info['transparency'] = bytes(transparency) # store the RGB channels in an ImagePalette palette_data = [color[i] for i in range(3) for color in colors] palette = ImagePalette.ImagePalette('RGB', palette_data, 3 * len(colors)) # use the indexed colors in the image palette palette_image.putpalette(palette) # record indexed data palette_image.putdata(index_data) return palette_image
def test_getdata(self): # test getheader/getdata against legacy values # Create a 'P' image with holes in the palette im = Image._wedge().resize((16, 16)) im.putpalette(ImagePalette.ImagePalette('RGB')) im.info = {'background': 0} passed_palette = bytes(bytearray([255 - i // 3 for i in range(768)])) GifImagePlugin._FORCE_OPTIMIZE = True try: h = GifImagePlugin.getheader(im, passed_palette) d = GifImagePlugin.getdata(im) import pickle # Enable to get target values on pre-refactor version # with open('Tests/images/gif_header_data.pkl', 'wb') as f: # pickle.dump((h, d), f, 1) with open('Tests/images/gif_header_data.pkl', 'rb') as f: (h_target, d_target) = pickle.load(f) self.assertEqual(h, h_target) self.assertEqual(d, d_target) finally: GifImagePlugin._FORCE_OPTIMIZE = False
def test_getdata(): # Arrange data_in = list(range(256)) * 3 palette = ImagePalette.ImagePalette("RGB", data_in) # Act mode, data_out = palette.getdata() # Assert assert mode == "RGB;L"
def test_getdata(self): # Arrange data_in = list(range(256)) * 3 palette = ImagePalette("RGB", data_in) # Act mode, data_out = palette.getdata() # Assert self.assertEqual(mode, "RGB;L")
def test_getcolor(): palette = ImagePalette() map = {} for i in range(256): map[palette.getcolor((i, i, i))] = i assert_equal(len(map), 256) assert_exception(ValueError, lambda: palette.getcolor((1, 2, 3)))
def test_getcolor(self): palette = ImagePalette() test_map = {} for i in range(256): test_map[palette.getcolor((i, i, i))] = i self.assertEqual(len(test_map), 256) self.assertRaises(ValueError, lambda: palette.getcolor((1, 2, 3)))
def __init__(self, palette_fp=None): P = ImagePalette.ImagePalette() for i in range(256): P.getcolor(tuple(i for _ in range(3))) self.palettes['grayscale'] = P clrs = [(80, 80, 80), (177, 0, 255), (44, 0, 255), (0, 222, 255), (0, 255, 22), (244, 255, 0), (255, 133, 0), (255, 0, 0)] P = ImagePalette.ImagePalette() for c in self.meta_colours: P.getcolor(c) for c in clrs: P.getcolor(c) for i in range(1, 241): v = min(8 * i, 255) P.getcolor((255, v, v)) self.palettes['default'] = P # for i in (3, 4, 6, 8, 12): self.palettes['r' + str(i)] = self.make_rainbow(i)
def create_palette(colormap, num): cmap = matplotlib.cm.get_cmap(colormap) palette = ImagePalette.ImagePalette() for n in range(num): val = n / num rgb = [int(255 * x) for x in cmap(val)[:-1]] palette.getcolor(tuple(rgb)) return palette
def toImage(self): palette = ImagePalette.ImagePalette("RGB") palette.dirty = 1 for i in range(256): k = (i * 48) % 256 palette.palette[i] = [k, k, k] w = self.char.width * 8 h = self.char.height * 8 data = self.char.toString() if not w or not h: return Image.fromstring("P", (1, 1), "\x00") return Image.fromstring("P", (w, h), data)
def test_palette_save_ImagePalette(self): # pass in a different palette, as an ImagePalette.ImagePalette # effectively the same as test_palette_save_P im = hopper('P') palette = ImagePalette.ImagePalette('RGB', list(range(256))[::-1] * 3) out = self.tempfile('temp.gif') im.save(out, palette=palette) reloaded = Image.open(out) im.putpalette(palette) self.assert_image_equal(reloaded, im)
def test_getcolor(self): palette = ImagePalette.ImagePalette() test_map = {} for i in range(256): test_map[palette.getcolor((i, i, i))] = i self.assertEqual(len(test_map), 256) self.assertRaises(ValueError, palette.getcolor, (1, 2, 3)) # Test unknown color specifier self.assertRaises(ValueError, palette.getcolor, "unknown")
def test_palette_save_ImagePalette(tmp_path): # Pass in a different palette, as an ImagePalette.ImagePalette # effectively the same as test_palette_save_P im = hopper("P") palette = ImagePalette.ImagePalette("RGB", list(range(256))[::-1] * 3) out = str(tmp_path / "temp.gif") im.save(out, palette=palette) with Image.open(out) as reloaded: im.putpalette(palette) assert_image_equal(reloaded, im)
def make_rainbow(self, sector_num): v, hs = self.rainbow_value, self.rainbow_hue_shift p = ImagePalette.ImagePalette() for c in self.meta_colours: p.getcolor(c) p.getcolor(tuple(self.zero_value for _ in range(3))) hvals = tuple( (hs - (1 + i) / sector_num) % 1.0 for i in range(sector_num)) for i in range(255 - len(p.colors)): p.getcolor( ImagerClass.hsv2rgb(hvals[i % sector_num], pow(0.5, i // sector_num), v)) return p
def test__new(self): im = hopper("RGB") im_p = hopper("P") blank_p = Image.new("P", (10, 10)) blank_pa = Image.new("PA", (10, 10)) blank_p.palette = None blank_pa.palette = None def _make_new(base_image, im, palette_result=None): new_im = base_image._new(im) assert new_im.mode == im.mode assert new_im.size == im.size assert new_im.info == base_image.info if palette_result is not None: assert new_im.palette.tobytes() == palette_result.tobytes() else: assert new_im.palette is None _make_new(im, im_p, im_p.palette) _make_new(im_p, im, None) _make_new(im, blank_p, ImagePalette.ImagePalette()) _make_new(im, blank_pa, ImagePalette.ImagePalette())
def motif(seed=None, is_webapp=False): seed = str(seed) if seed else str(random.randint(0, sys.maxsize)) random.seed(seed) palette = PaletteWrapper() seed_object = { 'base_seed': seed, 'horizon': int(random.triangular(IMAGE_SIZE[0] * 0.4, IMAGE_SIZE[0] * 0.8)), 'height': IMAGE_SIZE[0], 'width': IMAGE_SIZE[1], } funcs = [ stages.background, stages.moon, stages.mountains, stages.rocks, stages.water ] layers = [] for func in funcs: new_layers = func(layers, layer_factory, seed_object) if type(new_layers) == list: layers = layers + new_layers else: layers.append(new_layers) image = layer_factory('base', reflection.NONE).img for layer in layers: layer_img_data = list(layer.img.getdata()) image_data = image.getdata() image_data = [image_data[i] if layer_img_data[i] == colors.TRANSPARENT else layer_img_data[i] for i in range(len(image_data))] image.putdata(image_data) palette.set_colors(colors.generate_palette(seed_object)) image.putpalette(ImagePalette.ImagePalette('RGB', palette.serialize())) image = image.resize((IMAGE_SIZE[0] * 4, IMAGE_SIZE[1] * 4), resample=Image.NEAREST) if is_webapp: buffer = BytesIO() image.save(buffer, format='PNG') return (seed, base64.b64encode(buffer.getvalue())) else: image.show() image.save(f'img/motif_{int(time.time())}.png', 'PNG') print(f'Seed: {seed}')
def test_getcolor(): palette = ImagePalette.ImagePalette() test_map = {} for i in range(256): test_map[palette.getcolor((i, i, i))] = i assert len(test_map) == 256 with pytest.raises(ValueError): palette.getcolor((1, 2, 3)) # Test unknown color specifier with pytest.raises(ValueError): palette.getcolor("unknown")
def show(scan, place=None): rrrgggbbb = [40, 160, 50, 50, 20, 160, 150, 100, 0, 160, 250, 150] pal = ImagePalette.ImagePalette("RGB", rrrgggbbb, 12) if place is None: img = Image.fromarray(scan, mode="P") else: img = Image.fromarray( scan[max(0, place[0] - place[2]):min(scan.shape[0] - 1, place[0] + place[2]), max(0, place[1] - place[3]):min(scan.shape[1] - 1, place[1] + place[3])], mode="P") img = img.resize((img.size[0] * 10, img.size[1] * 10)) img.putpalette(pal) img.show()
def getPaletteOfImg(imgPath, contrast_val=1.0, color_val=1.0): img = Image.open(imgPath) pal = ImagePalette.ImagePalette() print(pal) contrast = contrast_img(img, contrast_val, color_val) print('contrast: {}'.format(contrast)) pal = img.getpalette() print(pal) newPalette = [] palette = Haishoku.getPalette(imgPath) for i in range(0, len(palette)): for j in palette[i][1]: newPalette.append(j) print(' Palette: {}'.format(newPalette)) return newPalette
def _new(self, im): new = Image() new.im = im new.mode = im.mode new.size = im.size if self.palette: new.palette = self.palette.copy() if im.mode == "P" and not new.palette: new.palette = ImagePalette.ImagePalette() try: new.info = self.info.copy() except AttributeError: # fallback (pre-1.5.2) new.info = {} for k, v in self.info: new.info[k] = v return new
def test_file(tmp_path): palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3) f = str(tmp_path / "temp.lut") palette.save(f) p = ImagePalette.load(f) # load returns raw palette information assert len(p[0]) == 768 assert p[1] == "RGB" p = ImagePalette.raw(p[1], p[0]) assert isinstance(p, ImagePalette.ImagePalette) assert p.palette == palette.tobytes()
def test_file(self): palette = ImagePalette.ImagePalette("RGB", list(range(256))*3) f = self.tempfile("temp.lut") palette.save(f) p = ImagePalette.load(f) # load returns raw palette information self.assertEqual(len(p[0]), 768) self.assertEqual(p[1], "RGB") p = ImagePalette.raw(p[1], p[0]) self.assertIsInstance(p, ImagePalette.ImagePalette) self.assertEqual(p.palette, palette.tobytes())
def _get_palette_bytes(im, palette, info): if im.mode == "P": if palette and isinstance(palette, bytes): source_palette = palette[:768] else: source_palette = im.im.getpalette("RGB")[:768] else: # L-mode if palette and isinstance(palette, bytes): source_palette = palette[:768] else: source_palette = bytearray([i // 3 for i in range(768)]) used_palette_colors = palette_bytes = None if _get_optimize(im, info): used_palette_colors = _get_used_palette_colors(im) # create the new palette if not every color is used if len(used_palette_colors) < 256: palette_bytes = b"" new_positions = {} i = 0 # pick only the used colors from the palette for oldPosition in used_palette_colors: palette_bytes += source_palette[oldPosition * 3:oldPosition * 3 + 3] new_positions[oldPosition] = i i += 1 # replace the palette color id of all pixel with the new id image_bytes = bytearray(im.tobytes()) for i in range(len(image_bytes)): image_bytes[i] = new_positions[image_bytes[i]] im.frombytes(bytes(image_bytes)) new_palette_bytes = (palette_bytes + (768 - len(palette_bytes)) * b'\x00') im.putpalette(new_palette_bytes) im.palette = ImagePalette.ImagePalette("RGB", palette=palette_bytes, size=len(palette_bytes)) if not palette_bytes: palette_bytes = source_palette return palette_bytes, used_palette_colors
def test_file(): palette = ImagePalette() file = tempfile("temp.lut") palette.save(file) from PIL.ImagePalette import load, raw p = load(file) # load returns raw palette information assert_equal(len(p[0]), 768) assert_equal(p[1], "RGB") p = raw(p[1], p[0]) assert_true(isinstance(p, ImagePalette))
def test_transparent_optimize(tmp_path): # From issue #2195, if the transparent color is incorrectly optimized out, GIF loses # transparency. # Need a palette that isn't using the 0 color, and one that's > 128 items where the # transparent color is actually the top palette entry to trigger the bug. data = bytes(range(1, 254)) palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3) im = Image.new("L", (253, 1)) im.frombytes(data) im.putpalette(palette) out = str(tmp_path / "temp.gif") im.save(out, transparency=253) with Image.open(out) as reloaded: assert reloaded.info["transparency"] == 253