A simple method is to use the force_original_aspect_ratio
option in the scale filter.

Original image. Represents a 640x480, 4:3 aspect ratio video.
In these examples the original image will be scaled to fit into a 1280x720, 16:9 aspect ratio output while preserving the original aspect ratio. To do this you can either:
Pillarbox or letterbox to fit

Pillarboxed image. Fitting a 640x480 (4:3) input into a 1280x720 (16:9) output.
ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1:color=black" output
This will upscale the image. If you want to avoid upscaling see the example below.
Letterboxing will occur instead of pillarboxing if the input aspect ratio is wider than the output aspect ratio. For example, an input with a 2.35:1 aspect ratio fit into a 16:9 output will result in letterboxing.
Same as above but without upscaling

640x480 (4:3) input into 1280x720 (16:9) output without upscaling.
ffmpeg -i input -vf "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:-1:-1:color=black" output
Crop to fit

Cropped image. 4:3 input aspect ratio, 16:9 output aspect ratio.
Using the crop filter to cut off the excess:
ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" output
Using input images that each vary in size
If you are inputting a series of images, and the images vary in size, add the eval=frame
option in the scale filter, such as:
ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=decrease:eval=frame,pad=1280:720:-1:-1:color=black" output
Changing the background color
Use the color
option in the pad filter. You can provide a hex value or use a supported color name.