Mark Farrell
Mark Farrell

Reputation: 39

How to scale images using float pixel sizes in Python PIL

I am pasting a slowly scaling up image onto a fixed size background inside a loop to create a smooth video of an image slowing zooming in.

However I can not find a way for my zoomed image to increase insize in between pixels as my float values must be converted into int before image resize, this creates a jittery effect where image scales up by pixel every 3 or 4 frames sometimes height and width separately as opposed to a smooth anti aliasing scale where "in between pixels" can be used and scaling occurs frame by frame no matter how small the increment up (like a texture on 3D game).

while currentFrame < (fbi - blendingFrames):
    #Slight zoom based on position
    zoomPosition = -(((fbi - blendingFrames - currentFrame) / framesbetweenImages)) + 1 #Creates value from 0 - 1 
    zoomScaleH = height+((height/20)*zoomPosition) #divide by height
    zoomScaleW = width+((width/20)*zoomPosition) #divide by width

    #converting to int here means some frames show no size increase
    img_w, img_h = int(zoomScaleW), int(zoomScaleH)
    outputimageZoomPaste = outputimageZoom.resize((img_w, img_h), Image.ANTIALIAS)

    offsetZ = ((width - img_w) // 2, (height - img_h) // 2)

    # Paste centered on to fixed size bk image #
    outputimage.paste(outputimageZoomPaste, offsetZ)

    #write frame to video
    video.write(cv2.cvtColor(np.array(outputimage), cv2.COLOR_RGB2BGR))
    currentFrame += 1

Upvotes: 2

Views: 2481

Answers (1)

N.D.C.
N.D.C.

Reputation: 1601

One way to avoid the jittering is to average between one expansion and the next. For instance if the image only increases in px size on frames 1,4,7,10, etc, on frame 1 we render image 1, and on frame 2 we render 66% image 1 and 33% image 4, and on frame 3 we render 33% image 1 and 66% image 4, and on frame 4 we render image 4. This makes the motion less sharp.

This is just one approach, but the point is the same: we can only increase image size in discrete pixel units, so the only way to create a gradient between pixels is to mix the outgoing and incoming colors.

Upvotes: 2

Related Questions