code: def get_img_output_shape(
      img_height: int,
      img_width: int,
      kernel_size: Union[int, Tuple[int]],
      stride: Union[int, Tuple[int]],
      padding: Union[int, Tuple[int], str],
      dilation: Union[int, Tuple[int]],
  ) -> Tuple[int]:
      """Returns the height and width of an image after a 2D img op.
  
      Currently supported for Conv2D, MaxPool2D and AvgPool2d ops.
      """
      if padding == "same":
          return (img_height, img_width)
      elif padding == "valid":
          padding = np.zeros(2)
      else:
          padding = to_np_tuple(padding)
  
      kernel_size = to_np_tuple(kernel_size)
      stride = to_np_tuple(stride)
      dilation = to_np_tuple(dilation)
      shape = np.array([img_height, img_width])
  
      out_shape = np.floor(
          (
              (shape + 2 * padding - dilation * (kernel_size - 1) - 1)
              / stride
          )
          + 1
      )
  
      return tuple(out_shape.astype(int))
  
imports: import logging
  import warnings
  from collections.abc import Iterable
  from dataclasses import dataclass
  from io import BytesIO
  from typing import Callable, List, Optional, Tuple, Union
  import numpy
  import tifffile
  import torch
  import torchvision.transforms.functional
  from torchvision.io import decode_image, ImageReadMode
  from torchvision.models._api import WeightsEnum
  from ludwig.api_annotations import DeveloperAPI
  from ludwig.constants import CROP_OR_PAD, INTERPOLATE
  from ludwig.encoders.base import Encoder
  from ludwig.utils.fs_utils import get_bytes_obj_from_path
  from ludwig.utils.registry import Registry
label_desc: Use image node_id 20 for calling a global function with example usage: get_img_output_shape(img_height, img_width, kernel_size, stride, padding, dilation) and returns: tuple, img_height,  img_width