mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 16:07:30 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			158 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from helper import unittest, PillowTestCase
 | |
| 
 | |
| from PIL import Image
 | |
| 
 | |
| try:
 | |
|     from PIL import _webp
 | |
|     HAVE_WEBP = True
 | |
| except ImportError:
 | |
|     HAVE_WEBP = False
 | |
| 
 | |
| 
 | |
| class TestFileWebpAnimation(PillowTestCase):
 | |
| 
 | |
|     def setUp(self):
 | |
|         if not HAVE_WEBP:
 | |
|             self.skipTest('WebP support not installed')
 | |
|             return
 | |
| 
 | |
|         if not _webp.HAVE_WEBPANIM:
 | |
|             self.skipTest("WebP library does not contain animation support, "
 | |
|                           "not testing animation")
 | |
| 
 | |
|     def test_n_frames(self):
 | |
|         """
 | |
|         Ensure that WebP format sets n_frames and is_animated
 | |
|         attributes correctly.
 | |
|         """
 | |
| 
 | |
|         im = Image.open("Tests/images/hopper.webp")
 | |
|         self.assertEqual(im.n_frames, 1)
 | |
|         self.assertFalse(im.is_animated)
 | |
| 
 | |
|         im = Image.open("Tests/images/iss634.webp")
 | |
|         self.assertEqual(im.n_frames, 42)
 | |
|         self.assertTrue(im.is_animated)
 | |
| 
 | |
|     def test_write_animation_L(self):
 | |
|         """
 | |
|         Convert an animated GIF to animated WebP, then compare the
 | |
|         frame count, and first and last frames to ensure they're
 | |
|         visually similar.
 | |
|         """
 | |
| 
 | |
|         orig = Image.open("Tests/images/iss634.gif")
 | |
|         self.assertGreater(orig.n_frames, 1)
 | |
| 
 | |
|         temp_file = self.tempfile("temp.webp")
 | |
|         orig.save(temp_file, save_all=True)
 | |
|         im = Image.open(temp_file)
 | |
|         self.assertEqual(im.n_frames, orig.n_frames)
 | |
| 
 | |
|         # Compare first and last frames to the original animated GIF
 | |
|         orig.load()
 | |
|         im.load()
 | |
|         self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
 | |
|         orig.seek(orig.n_frames-1)
 | |
|         im.seek(im.n_frames-1)
 | |
|         orig.load()
 | |
|         im.load()
 | |
|         self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
 | |
| 
 | |
|     def test_write_animation_RGB(self):
 | |
|         """
 | |
|         Write an animated WebP from RGB frames, and ensure the frames
 | |
|         are visually similar to the originals.
 | |
|         """
 | |
| 
 | |
|         def check(temp_file):
 | |
|             im = Image.open(temp_file)
 | |
|             self.assertEqual(im.n_frames, 2)
 | |
| 
 | |
|             # Compare first frame to original
 | |
|             im.load()
 | |
|             self.assert_image_equal(im, frame1.convert("RGBA"))
 | |
| 
 | |
|             # Compare second frame to original
 | |
|             im.seek(1)
 | |
|             im.load()
 | |
|             self.assert_image_equal(im, frame2.convert("RGBA"))
 | |
| 
 | |
|         frame1 = Image.open('Tests/images/anim_frame1.webp')
 | |
|         frame2 = Image.open('Tests/images/anim_frame2.webp')
 | |
| 
 | |
|         temp_file1 = self.tempfile("temp.webp")
 | |
|         frame1.copy().save(temp_file1,
 | |
|                            save_all=True, append_images=[frame2],
 | |
|                            lossless=True)
 | |
|         check(temp_file1)
 | |
| 
 | |
|         # Tests appending using a generator
 | |
|         def imGenerator(ims):
 | |
|             for im in ims:
 | |
|                 yield im
 | |
|         temp_file2 = self.tempfile("temp_generator.webp")
 | |
|         frame1.copy().save(temp_file2,
 | |
|                            save_all=True, append_images=imGenerator([frame2]),
 | |
|                            lossless=True)
 | |
|         check(temp_file2)
 | |
| 
 | |
|     def test_timestamp_and_duration(self):
 | |
|         """
 | |
|         Try passing a list of durations, and make sure the encoded
 | |
|         timestamps and durations are correct.
 | |
|         """
 | |
| 
 | |
|         durations = [0, 10, 20, 30, 40]
 | |
|         temp_file = self.tempfile("temp.webp")
 | |
|         frame1 = Image.open('Tests/images/anim_frame1.webp')
 | |
|         frame2 = Image.open('Tests/images/anim_frame2.webp')
 | |
|         frame1.save(temp_file, save_all=True,
 | |
|                     append_images=[frame2, frame1, frame2, frame1],
 | |
|                     duration=durations)
 | |
| 
 | |
|         im = Image.open(temp_file)
 | |
|         self.assertEqual(im.n_frames, 5)
 | |
|         self.assertTrue(im.is_animated)
 | |
| 
 | |
|         # Check that timestamps and durations match original values specified
 | |
|         ts = 0
 | |
|         for frame in range(im.n_frames):
 | |
|             im.seek(frame)
 | |
|             im.load()
 | |
|             self.assertEqual(im.info["duration"], durations[frame])
 | |
|             self.assertEqual(im.info["timestamp"], ts)
 | |
|             ts += durations[frame]
 | |
| 
 | |
|     def test_seeking(self):
 | |
|         """
 | |
|         Create an animated WebP file, and then try seeking through
 | |
|         frames in reverse-order, verifying the timestamps and durations
 | |
|         are correct.
 | |
|         """
 | |
| 
 | |
|         dur = 33
 | |
|         temp_file = self.tempfile("temp.webp")
 | |
|         frame1 = Image.open('Tests/images/anim_frame1.webp')
 | |
|         frame2 = Image.open('Tests/images/anim_frame2.webp')
 | |
|         frame1.save(temp_file, save_all=True,
 | |
|                     append_images=[frame2, frame1, frame2, frame1],
 | |
|                     duration=dur)
 | |
| 
 | |
|         im = Image.open(temp_file)
 | |
|         self.assertEqual(im.n_frames, 5)
 | |
|         self.assertTrue(im.is_animated)
 | |
| 
 | |
|         # Traverse frames in reverse, checking timestamps and durations
 | |
|         ts = dur * (im.n_frames-1)
 | |
|         for frame in reversed(range(im.n_frames)):
 | |
|             im.seek(frame)
 | |
|             im.load()
 | |
|             self.assertEqual(im.info["duration"], dur)
 | |
|             self.assertEqual(im.info["timestamp"], ts)
 | |
|             ts -= dur
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     unittest.main()
 |