code: def get_sub_rectangles(self, ims):
          
  
          # Check image count
          if len(ims) < 2:
              return ims, [(0, 0) for i in ims]
  
          # We need numpy
          if np is None:
              raise RuntimeError("Need Numpy to calculate sub-rectangles. ")
  
          # Prepare
          ims2 = [ims[0]]
          xy = [(0, 0)]
  
          # Iterate over images
          prev = ims[0]
          for im in ims[1:]:
  
              # Get difference, sum over colors
              diff = np.abs(im - prev)
              if diff.ndim == 3:
                  diff = diff.sum(2)
              # Get begin and end for both dimensions
              x = np.argwhere(diff.sum(0))
              y = np.argwhere(diff.sum(1))
              # Get rect coordinates
              if x.size and y.size:
                  x0, x1 = x[0], x[-1] + 1
                  y0, y1 = y[0], y[-1] + 1
              else:  # No change ... make it minimal
                  x0, x1 = 0, 2
                  y0, y1 = 0, 2
  
              # Cut out and store
              im2 = im[y0:y1, x0:x1]
              prev = im
              ims2.append(im2)
              xy.append((x0, y0))
  
          return ims2, xy
docs: get_sub_rectangles(ims)
  
          Calculate the minimal rectangles that need updating each frame.
          Returns a two-element tuple containing the cropped images and a
          list of x-y positions.
  
          Calculating the subrectangles takes extra time, obviously. However,
          if the image sizes were reduced, the actual writing of the GIF
          goes faster. In some cases applying this method produces a GIF faster.