Skip to content

Instantly share code, notes, and snippets.

@yuchen-xue
Created April 12, 2025 12:42
Show Gist options
  • Save yuchen-xue/1420209043bf23ad846ed77b1caf8da5 to your computer and use it in GitHub Desktop.
Save yuchen-xue/1420209043bf23ad846ed77b1caf8da5 to your computer and use it in GitHub Desktop.
Resize an image to a target width and height, while keeping the original height-width ratio. If the original height-width ratio is different from the target height-width ratio, fill the rest of the area with white pixels.
import argparse
from pathlib import Path
import cv2
import numpy.typing as npt
def resize_white_fill(img: npt.NDArray, w_target: int, h_target: int) -> npt.NDArray:
"""Resize an image to a target width and height, while keeping the original
height-width ratio. If the original height-width ratio is different from
the target height-width ratio, fill the rest of the area with white pixels.
Args:
img (npt.NDArray): _Input image_
w_target (int): _The desired width of the output image_
h_target (int): _The desired height of the output image_
Returns:
npt.NDArray: _The resized image with white pixels filling the rest of the area_
"""
# Get the height-width ratio ("h-w ratio" for short) of the input image
h, w = img.shape[:2]
r = h / w
# If the input image has the identical h-w ratio as desired, simply
# resize this image as the given height and width, without further operations.
if r == h_target / w_target:
return cv2.resize(img, (w_target, h_target))
# Below are the additional operations in case the input image has a different
# h-w ratio as desired.
elif int(w_target * r) < h_target:
# Suppose we resize the image so that it has the same width as the desired
# width, then we compare the new height with the desired height. If its
# height is smaller to the desired height.
w_new = w_target
h_new = int(w_new * r)
resized = cv2.resize(img, (w_new, h_new), interpolation=cv2.INTER_AREA)
# Fill the rest of the area along the height with white pixels
pad_height_top = int((h_target - h_new) / 2)
pad_height_bottom = h_target - h_new - pad_height_top
return cv2.copyMakeBorder(
resized,
top=pad_height_top,
bottom=pad_height_bottom,
left=0,
right=0,
borderType=cv2.BORDER_CONSTANT,
value=(255, 255, 255)
)
else:
# If the new height exceeds the desired height, we resize the image so that
# its height fit into the desired height instead.
h_new = h_target
w_new = int(h_new / r)
resized = cv2.resize(img, (w_new, h_new), interpolation=cv2.INTER_AREA)
# Fill the rest of the area along the width with white pixels
pad_width_left = int((w_target - w_new) / 2)
pad_width_right = w_target - w_new - pad_width_left
return cv2.copyMakeBorder(
resized,
top=0,
bottom=0,
left=pad_width_left,
right=pad_width_right,
borderType=cv2.BORDER_CONSTANT,
value=(255, 255, 255)
)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Resize images to a target width\n"
"and height with white fill.")
parser.add_argument("--input", "-i", type=str,
help="Path to the input image.")
parser.add_argument("--output", "-o", type=str,
help="Path to the output image.")
parser.add_argument("--width", "-wt", type=int,
help="The desired width of the output image.")
parser.add_argument("--height", "-ht", type=int,
help="The desired height of the output image.")
args = parser.parse_args()
# Read the input image
img = cv2.imread(str(Path(args.input).resolve()))
# Resize the image
resized_img = resize_white_fill(img, args.width, args.height)
# Save the resized image
cv2.imwrite(str(Path(args.output).resolve()), resized_img)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment