在Python中,如何在不调整大小的情况下扩展Python图像库1.1.6的画布?
我可能在手册里找错了东西,但我想要做的是把一个图片对象扩展,而不是改变原始图片的大小(拉伸或压缩)。
举个简单的例子:想象一个蓝色的矩形,大小是200 x 100,然后我进行一些操作,得到一个新的图片对象,大小是400 x 300,这个新图片有一个白色的背景,上面放着一个200 x 100的蓝色矩形。如果我能控制扩展的方向,或者新背景的颜色,那就更好了。
基本上,我有一张图片,我会逐步添加内容,但我一开始不知道它会变成多大。
我想我可以先拿到原始对象,做一个稍微大一点的新对象,把原始图片粘贴上去,再画一点东西,然后重复这个过程。这样做可能会消耗很多计算资源。不过,我以为应该有一个函数可以直接实现这个,因为我觉得这是个常见的操作。也许我想错了。
4 个回答
6
你可以考虑用一种完全不同的方法来处理你的图像……把它分成固定大小的小块。这样,当你需要扩展时,只需添加新的图像小块就可以了。当你完成所有计算后,可以确定图像的最终大小,然后创建一个空白的图像,按照需要的大小把小块粘贴进去。这样可以减少你在完成任务时需要复制的内容。
当然,你可能还想把这种分块的图像封装成一个对象,这样其他代码层就看不到这些分块的细节了。
18
根据interjays的回答:
#!/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):
"""
Resize the canvas of old_image_path.
Store the new image in new_image_path. Center the image on the new canvas.
Parameters
----------
old_image_path : str
new_image_path : str
canvas_width : int
canvas_height : int
"""
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()
35
ImageOps.expand这个函数会把图片扩展,但它会在每个方向上添加相同数量的像素。
最简单的方法就是新建一张图片,然后把原来的图片粘贴上去:
newImage = Image.new(mode, (newWidth,newHeight))
newImage.paste(srcImage, (x1,y1,x1+oldWidth,y1+oldHeight))
如果你担心性能问题,可以先把原始图片做得比需要的大,然后在绘制完成后再裁剪。