在 Python, Python Image Library 1.1.6 中,如何在不调整大小的情况下扩展画布?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1572691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Python, Python Image Library 1.1.6, how can I expand the canvas without resizing?
提问by MetaHyperBolic
I am probably looking for the wrong thing in the handbook, but I am looking to take an image object and expand it without resizing (stretching/squishing) the original image.
我可能在手册中寻找错误的内容,但我希望获取图像对象并扩展它而不调整(拉伸/挤压)原始图像的大小。
Toy example: imagine a blue rectangle, 200 x 100, then I perform some operation and I have a new image object, 400 x 300, consisting of a white background upon which a 200 x 100 blue rectangle rests. Bonus if I can control in which direction this expands, or the new background color, etc.
玩具示例:想象一个蓝色矩形,200 x 100,然后我执行一些操作,我有一个新的图像对象,400 x 300,由一个白色背景组成,上面有一个 200 x 100 的蓝色矩形。如果我可以控制它向哪个方向扩展,或者新的背景颜色等,那就再好不过了。
Essentially, I have an image to which I will be adding iteratively, and I do not know what size it will be at the outset.
本质上,我有一个我将迭代添加的图像,一开始我不知道它的大小。
I suppose it would be possible for me to grab the original object, make a new, slightly larger object, paste the original on there, draw a little more, then repeat. It seems like it might be computationally expensive. However, I thought there would be a function for this, as I assume it is a common operation. Perhaps I assumed wrong.
我想我可以抓住原始对象,制作一个新的、稍大的对象,将原始对象粘贴在那里,再画一点,然后重复。看起来它可能在计算上很昂贵。但是,我认为会有一个功能,因为我认为这是一个常见的操作。也许我假设错了。
回答by interjay
The ImageOps.expand function will expand the image, but it adds the same amount of pixels in each direction.
ImageOps.expand 函数将扩展图像,但它会在每个方向添加相同数量的像素。
The best way is simply to make a new image and paste:
最好的方法是简单地制作一个新图像并粘贴:
newImage = Image.new(mode, (newWidth,newHeight))
newImage.paste(srcImage, (x1,y1,x1+oldWidth,y1+oldHeight))
If performance is an issue, make your original image bigger than needed and crop it after the drawing is done.
如果性能是一个问题,请使原始图像比需要的大,并在绘图完成后进行裁剪。
回答by Martin Thoma
Based on interjays answer:
基于 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()
回答by retracile
You might consider a rather different approach to your image... build it out of tiles of a fixed size. That way, as you need to expand, you just add new image tiles. When you have completed all of your computation, you can determine the final size of the image, create a blank image of that size, and paste the tiles into it. That should reduce the amount of copying you're looking at for completing the task.
您可能会考虑对图像采用一种完全不同的方法……用固定大小的图块构建它。这样,当您需要扩展时,您只需添加新的图像块。完成所有计算后,您可以确定图像的最终尺寸,创建该尺寸的空白图像,然后将图块粘贴到其中。这应该会减少您为完成任务而查看的复制量。
(You'd likely want to encapsulate such a tiled image into an object that hid the tiling aspects from the other layers of code, of course.)
(当然,您可能希望将这样的平铺图像封装到一个对象中,该对象对其他代码层隐藏平铺方面。)