docs: def sort_image_tiles(image, size, sorting_args, tile_size, tile_density=1.0, randomize_tiles=False):
      """
      Sorts an image by taking various tiles and sorting them individually.
      :param image: The image to be modified
      :param size: The size of the image, as (width, height)
      :param sorting_args: Arguments that would be passed to sort_pixels for each tile
      :param tile_size: The size of each tile as (width, height)
      :param tile_density: What fraction of the image is covered in tiles.
      :param randomize_tiles: Whether tiles should be distributed randomly
      :return: The modified image
      """
      out_image = list(image)
      width, height = size
      tile_width, tile_height = tile_size
  
      i = 0
      total_tiles = ceil(height / float(tile_height)) * ceil(width / float(tile_width))
      tiles_completed = 0
      pixels_per_tiles = tile_width * tile_height
      for y in range(0, height, tile_height):
          for x in range(0, width, tile_width):
              # logging
              tiles_completed += 1
              if tiles_completed % (200000 / pixels_per_tiles) == 0:
                  logger.info("Completed %d / %d tiles... (%2.2f%%)" %
                              (tiles_completed, total_tiles, 100.0 * tiles_completed / total_tiles))
  
              i += 1
              if randomize_tiles:
                  # if using randomized tiles, skip a tile with probability 1 - density
                  r = random()
                  if r >= tile_density:
                      continue
              else:
                  # if tiles are not randomized, add a tile once every 1/density times
                  if tile_density == 0 or i < 1.0 / tile_density:
                      continue
                  else:
                      i -= 1.0 / tile_density
              # extract a tile, sort it, and copy it back to the image
              tile, current_tile_size = get_tile_from_image(image, size, (x, y), tile_size)
              sorted_tile = sort_image(tile, current_tile_size, **sorting_args)
              apply_tile_to_image(out_image, size, sorted_tile, current_tile_size, (x, y))
  
      return out_image