It seems to be no easy way for resizing ( liquid resizing doesn't work here ) except (as suggested in the question with the second image) dividing the image using PIL crop()
into nine (9) sub-images and resize them separately (except the corner sub-images, which won't become resized). The resized parts are then put together in a new image with the requested new size by pasting them using PIL paste()
onto it. The borders are stretched only along their length and not along their thickness. Here how it looks like if the original image becomes resized with the further down provided resizeExceptBorder()
function:
Original image (200 x 30)
new_img_1 = resizeExceptBorder(PIL_image,(300,90),(5,5,5,5))
Resized image (300 x 90)
new_img_2 = resizeExceptBorder(PIL_image,(400,150),(5,5,5,5))
Resized (400 x 150)
And here the code of the function I have put together for this purpose:
def resizeExceptBorder(PIL_image, newSize, borderWidths):
"""
newSize = (new_width, new_height)
borderWidths = (leftWidth, rightWidth, topWidth, bottomWidth)"""
pl_img = PIL_image
sXr, sYr = newSize # ( 800, 120 ) # resized size X, Y
lWx, rWx , tWy, bWy = borderWidths
sX, sY = pl_img.size
sXi, sYi = sXr-(lWx+rWx), sYr-(tWy+bWy)
pl_lft_top = pl_img.crop(( 0, 0, lWx, tWy))
pl_rgt_top = pl_img.crop((sX-rWx, 0, sX, tWy))
pl_lft_btm = pl_img.crop(( 0, sY-bWy, lWx, sY))
pl_rgt_btm = pl_img.crop((sX-rWx, sY-bWy, sX, sY))
# ---
pl_lft_lft = pl_img.crop(( 0, tWy, lWx,sY-bWy)).resize((lWx ,sYi))
pl_rgt_rgt = pl_img.crop((sX-rWx, tWy, sX,sY-bWy)).resize((rWx ,sYi))
pl_top_top = pl_img.crop(( lWx, 0, sX-rWx, tWy)).resize((sXi ,tWy))
pl_btm_btm = pl_img.crop(( lWx, sY-bWy, sX-rWx, sY)).resize((sXi ,bWy))
# ---
pl_mid_mid = pl_img.crop(( lWx, tWy, sX-rWx,sY-bWy)).resize((sXi,sYi))
# -------
pl_new=Image.new(pl_img.mode, (sXr, sYr))
# ---
pl_new.paste(pl_mid_mid, ( lWx, tWy))
# ---
pl_new.paste(pl_top_top, ( lWx, 0))
pl_new.paste(pl_btm_btm, ( lWx,sYr-bWy))
pl_new.paste(pl_lft_lft, ( 0, tWy))
pl_new.paste(pl_rgt_rgt, (sXr-rWx, tWy))
# ---
pl_new.paste(pl_lft_top, ( 0, 0))
pl_new.paste(pl_rgt_top, (sXr-rWx, 0))
pl_new.paste(pl_lft_btm, ( 0,sYr-bWy))
pl_new.paste(pl_rgt_btm, (sXr-rWx,sYr-bWy))
# ---
return pl_new
#:def