Use Image class to resize datasets with aspect ratio?

Does anyone have code they can share to resize images using FastAI2 while preserving aspect ratio for dataset creation?

Update - some progress with this:

pil = PILImage.create(fullimg[0])
pil=pil.resize_max(resample = Image.BICUBIC,max_h=500, max_w=500)
img_quality=100
newname = 'resize.jpg'

savefile = resize_dir/ newname;savefile

pil.save(savefile, quality=img_quality)

#checking new image

check = PILImage.create(savefile)

check.size   #   verify image size

I was trying to pull the ResizeRatio code out from transforms to just make a resizer class but the transforms have a lot of built in dependencies.

I’d like to have prebuiilt datasets for various px sizes instead of redoing it every time I train basically.

The resize_max appears to preserve aspect ratio but not 100% sure (comments in the code would be…):

def resize_max(x: Image.Image, resample=0, max_px=None, max_h=None, max_w=None):
    "`resize` `x` to `max_px`, or `max_h`, or `max_w`"
    h,w = x.shape
    if max_px and x.n_px>max_px: h,w = Tuple(h,w).mul(math.sqrt(max_px/x.n_px))
    if max_h and h>max_h: h,w = (max_h    ,max_h*w/h)
    if max_w and w>max_w: h,w = (max_w*h/w,max_w    )
    return x.reshape(round(h), round(w), resample=resample)

or should we just do this with regular PIL? I was using this code from the docs in v1:

    path_hr = path/'images'
path_Cloud = path/'res-456'
path_Cell = path/'res-300'

img_quality = 100 # b/c this is med diagnostic we want to use max quality

il = ImageList.from_folder(path_hr)

def resize_one(fn, i, path, size):
    dest = path/fn.relative_to(path_hr)
    dest.parent.mkdir(parents=True, exist_ok=True)
    img = PIL.Image.open(fn)
    targ_sz = resize_to(img, size, use_min=True)
    img = img.resize(targ_sz, resample=PIL.Image.BILINEAR).convert('RGB')
    img.save(dest, quality=img_quality)

# create smaller image sets the first time this nb is run
sets = [(path_Cloud, 456), (path_Cell, 300)]
for p,size in sets:
    if not p.exists(): 
        print(f"resizing to {size} into {p}")
        parallel(partial(resize_one, path=p, size=size), il.items)