mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 16:07:30 +03:00 
			
		
		
		
	Optimise palettes with more than 128 colors
This commit is contained in:
		
							parent
							
								
									f656711c80
								
							
						
					
					
						commit
						709744432a
					
				|  | @ -158,6 +158,9 @@ def test_optimize_correctness(): | |||
|             assert_image_equal(im.convert("RGB"), reloaded.convert("RGB")) | ||||
| 
 | ||||
|     # These do optimize the palette | ||||
|     check(256, 511, 256) | ||||
|     check(255, 511, 255) | ||||
|     check(129, 511, 129) | ||||
|     check(128, 511, 128) | ||||
|     check(64, 511, 64) | ||||
|     check(4, 511, 4) | ||||
|  | @ -167,11 +170,6 @@ def test_optimize_correctness(): | |||
|     check(64, 513, 256) | ||||
|     check(4, 513, 256) | ||||
| 
 | ||||
|     # Other limits that don't optimize the palette | ||||
|     check(129, 511, 256) | ||||
|     check(255, 511, 256) | ||||
|     check(256, 511, 256) | ||||
| 
 | ||||
| 
 | ||||
| def test_optimize_full_l(): | ||||
|     im = Image.frombytes("L", (16, 16), bytes(range(256))) | ||||
|  | @ -182,17 +180,15 @@ def test_optimize_full_l(): | |||
| 
 | ||||
| def test_optimize_if_palette_can_be_reduced_by_half(): | ||||
|     with Image.open("Tests/images/test.colors.gif") as im: | ||||
|         # Reduce because original is too big for _get_optimize() | ||||
|         # Reduce dimensions because original is too big for _get_optimize() | ||||
|         im = im.resize((591, 443)) | ||||
|         imrgb = im.convert("RGB") | ||||
|     im_rgb = im.convert("RGB") | ||||
| 
 | ||||
|     for (optimize, colors) in ((False, 256), (True, 8)): | ||||
|         out = BytesIO() | ||||
|         imrgb.save(out, "GIF", optimize=False) | ||||
|         im_rgb.save(out, "GIF", optimize=optimize) | ||||
|         with Image.open(out) as reloaded: | ||||
|             assert len(reloaded.palette.palette) // 3 == 256 | ||||
|         out = BytesIO() | ||||
|         imrgb.save(out, "GIF", optimize=True) | ||||
|         with Image.open(out) as reloaded: | ||||
|             assert len(reloaded.palette.palette) // 3 == 8 | ||||
|             assert len(reloaded.palette.palette) // 3 == colors | ||||
| 
 | ||||
| 
 | ||||
| def test_roundtrip(tmp_path): | ||||
|  | @ -997,8 +993,8 @@ def test_append_images(tmp_path): | |||
| 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. | ||||
|     # Need a palette that isn't using the 0 color, | ||||
|     # 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) | ||||
|  | @ -1008,10 +1004,10 @@ def test_transparent_optimize(tmp_path): | |||
|     im.putpalette(palette) | ||||
| 
 | ||||
|     out = str(tmp_path / "temp.gif") | ||||
|     im.save(out, transparency=253) | ||||
|     with Image.open(out) as reloaded: | ||||
|     im.save(out, transparency=im.getpixel((252, 0))) | ||||
| 
 | ||||
|         assert reloaded.info["transparency"] == 253 | ||||
|     with Image.open(out) as reloaded: | ||||
|         assert reloaded.info["transparency"] == reloaded.getpixel((252, 0)) | ||||
| 
 | ||||
| 
 | ||||
| def test_rgb_transparency(tmp_path): | ||||
|  |  | |||
|  | @ -824,18 +824,15 @@ def _get_optimize(im, info): | |||
|                 if count: | ||||
|                     used_palette_colors.append(i) | ||||
| 
 | ||||
|             num_palette_colors = ( | ||||
|                 len(im.palette.palette) // 4 | ||||
|                 if im.palette.mode == "RGBA" | ||||
|                 else len(im.palette.palette) // 3 | ||||
|             if optimise or max(used_palette_colors) >= len(used_palette_colors): | ||||
|                 return used_palette_colors | ||||
| 
 | ||||
|             num_palette_colors = len(im.palette.palette) // Image.getmodebands( | ||||
|                 im.palette.mode | ||||
|             ) | ||||
|             # Round up to power of 2 but at least 4 | ||||
|             num_palette_colors = max(4, 1 << (num_palette_colors - 1).bit_length()) | ||||
|             if optimise or ( | ||||
|                 len(used_palette_colors) <= 128 | ||||
|                 and max(used_palette_colors) >= len(used_palette_colors) | ||||
|                 or len(used_palette_colors) <= num_palette_colors // 2 | ||||
|             ): | ||||
|             if len(used_palette_colors) <= num_palette_colors // 2: | ||||
|                 return used_palette_colors | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user