def compute_new_image_size(image_size: tuple, tile_size: tuple, stride: tuple) -> tuple:
    """Compute new image size that is divisible by tile size and stride.

    Args:
        image_size: Original image size as ``(height, width)``
        tile_size: Tile size as ``(height, width)``
        stride: Stride size as ``(height, width)``

    Returns:
        tuple: New image size divisible by tile size and stride

    Examples:
        >>> compute_new_image_size((512, 512), (256, 256), (128, 128))
        (512, 512)
        >>> compute_new_image_size((512, 512), (222, 222), (111, 111))
        (555, 555)
    """

    def __compute_new_edge_size(edge_size: int, tile_size: int, stride: int) -> int:
        """Compute new edge size that is divisible by tile size and stride.

        Args:
            edge_size: Original edge size
            tile_size: Tile size for this edge
            stride: Stride size for this edge

        Returns:
            int: New edge size
        """
        if (edge_size - tile_size) % stride != 0:
            edge_size = (ceil((edge_size - tile_size) / stride) * stride) + tile_size

        return edge_size

    resized_h = __compute_new_edge_size(image_size[0], tile_size[0], stride[0])
    resized_w = __compute_new_edge_size(image_size[1], tile_size[1], stride[1])

    return resized_h, resized_w
Compute new image size that is divisible by tile size and stride.

    Args:
        image_size: Original image size as ``(height, width)``
        tile_size: Tile size as ``(height, width)``
        stride: Stride size as ``(height, width)``

    Returns:
        tuple: New image size divisible by tile size and stride

    Examples:
        >>> compute_new_image_size((512, 512), (256, 256), (128, 128))
        (512, 512)
        >>> compute_new_image_size((512, 512), (222, 222), (111, 111))
        (555, 555)
    
src/anomalib/data/utils/tiler.py