I need to take an image and place it onto a new, generated white background in order for it to be converted into a downloadable desktop wallpaper. So the process would go:
- Generate new, all white image with 1440x900 dimensions
- Place existing image on top, centered
- Save as single image
In PIL, I see the ImageDraw
object, but nothing indicates it can draw existing image data onto another image. Suggestions or links anyone can recommend?
This can be accomplished with an Image instance's paste
method:
from PIL import Image
img = Image.open('/path/to/file', 'r')
img_w, img_h = img.size
background = Image.new('RGBA', (1440, 900), (255, 255, 255, 255))
bg_w, bg_h = background.size
offset = ((bg_w - img_w) // 2, (bg_h - img_h) // 2)
background.paste(img, offset)
background.save('out.png')
This and many other PIL tricks can be picked up at Nadia Alramli's PIL Tutorial
Based on unutbus answer:
#!/usr/bin/env python
from PIL import Image
import math
def resize_canvas(old_image_path="314.jpg", new_image_path="save.jpg",
canvas_width=500, canvas_height=500):
"""
Place one image on another image.
Resize the canvas of old_image_path and store the new image in
new_image_path. Center the image on the new canvas.
"""
im = Image.open(old_image_path)
old_width, old_height = im.size
# Center the image
x1 = int(math.floor((canvas_width - old_width) / 2))
y1 = int(math.floor((canvas_height - old_height) / 2))
mode = im.mode
if len(mode) == 1: # L, 1
new_background = (255)
if len(mode) == 3: # RGB
new_background = (255, 255, 255)
if len(mode) == 4: # RGBA, CMYK
new_background = (255, 255, 255, 255)
newImage = Image.new(mode, (canvas_width, canvas_height), new_background)
newImage.paste(im, (x1, y1, x1 + old_width, y1 + old_height))
newImage.save(new_image_path)
resize_canvas()
Remember to use Pillow (Documentation, GitHub, PyPI) instead of python-imaging as Pillow works with Python 2.X and Python 3.X.
This is to do something similar
Where I started was by generating that 'white background' in photoshop and exporting it as a PNG file. Thats where I got im1 (Image 1). Then used the paste function cause it's way easier.
from PIL import Image
im1 = Image.open('image/path/1.png')
im2 = Image.open('image/path/2.png')
area = (40, 1345, 551, 1625)
im1.paste(im2, area)
l>(511+40) l>(280+1345)
| l> From 0 (move, 1345px down)
-> From 0 (top left, move 40 pixels right)
Okay so where did these #'s come from?
(40, 1345, 551, 1625)
im2.size
(511, 280)
Because I added 40 right and 1345 down (40, 1345, 511, 280) I must add them to the original image size which = (40, 1345, 551, 1625)
im1.show()
to show your new image
Image.blend()
? [link]
Or, better yet, Image.paste()
, same link.
Maybe too late, but for such image operations, we do use ImageSpecField [link] in model with original image.