【问题标题】:How do you merge images into a canvas using PIL/Pillow?如何使用 PIL/Pillow 将图像合并到画布中?
【发布时间】:2012-05-25 17:08:14
【问题描述】:

我不熟悉 PIL,但我知道在 ImageMagick 中将一堆图像放入一个网格中非常容易。

例如,我如何将 16 张图像放入一个 4×4 的网格中,我可以在其中指定行和列之间的间距?

【问题讨论】:

    标签: python image canvas python-imaging-library pillow


    【解决方案1】:

    扩展了 fraxel 的出色答案,我编写了一个程序,该程序接收一个包含 (.png) 图像的文件夹、拼贴宽度的像素数以及每行图片的数量,并完成所有为您计算。

    #Evan Russenberger-Rosica
    #Create a Grid/Matrix of Images
    import PIL, os, glob
    from PIL import Image
    from math import ceil, floor
    
    PATH = r"C:\Users\path\to\images"
    
    frame_width = 1920
    images_per_row = 5
    padding = 2
    
    os.chdir(PATH)
    
    images = glob.glob("*.png")
    images = images[:30]                #get the first 30 images
    
    img_width, img_height = Image.open(images[0]).size
    sf = (frame_width-(images_per_row-1)*padding)/(images_per_row*img_width)       #scaling factor
    scaled_img_width = ceil(img_width*sf)                   #s
    scaled_img_height = ceil(img_height*sf)
    
    number_of_rows = ceil(len(images)/images_per_row)
    frame_height = ceil(sf*img_height*number_of_rows) 
    
    new_im = Image.new('RGB', (frame_width, frame_height))
    
    i,j=0,0
    for num, im in enumerate(images):
        if num%images_per_row==0:
            i=0
        im = Image.open(im)
        #Here I resize my opened image, so it is no bigger than 100,100
        im.thumbnail((scaled_img_width,scaled_img_height))
        #Iterate through a 4 by 4 grid with 100 spacing, to place my image
        y_cord = (j//images_per_row)*scaled_img_height
        new_im.paste(im, (i,y_cord))
        print(i, y_cord)
        i=(i+scaled_img_width)+padding
        j+=1
    
    new_im.show()
    new_im.save("out.jpg", "JPEG", quality=80, optimize=True, progressive=True)
    

    【讨论】:

    • 嗨。你的答案看起来很棒。你知道如何避免图片边缘的黑线吗?
    • @IrbinB。当我写这篇文章时,我希望图像之间的划分清晰,所以我包括了水平和垂直填充(黑线)。垂直填充由代码中的 padding 参数给出,因此只需将其设置为 0 即可删除它们。水平填充不小心被硬编码了,我离开它是因为我想要那种效果。我必须尝试找出如何删除水平填充;每个循环都会有 1 个像素的偏差。
    • 感谢您的回复。当然,我意识到 padding 参数但将其设置为 0 对我不起作用。奇怪的是,我的最终图像中只出现了垂直填充。也许我应该提出一个新问题。
    • @IrbinB。尝试将:scaled_img_height = ceil(img_height*sf) 更改为 scaled_img_height = floor(img_height*sf)。那应该删除水平线。例如,我将同一张图片(imgur.com/a/AtyrAR5)复制了 30 张,并将它们输入到更改后的程序中,得到:imgur.com/a/kbdga0G
    • 它没有用。但我已经解决了我的问题。我发现问题与我的图像文件有关。所以,你的代码没有问题。谢谢。
    【解决方案2】:

    这在PIL 中也很容易做到。创建一个空图像,然后使用paste 将您想要的图像粘贴到您需要的任何位置。这是一个简单的例子:

    import Image
    
    #opens an image:
    im = Image.open("1_tree.jpg")
    #creates a new empty image, RGB mode, and size 400 by 400.
    new_im = Image.new('RGB', (400,400))
    
    #Here I resize my opened image, so it is no bigger than 100,100
    im.thumbnail((100,100))
    #Iterate through a 4 by 4 grid with 100 spacing, to place my image
    for i in xrange(0,500,100):
        for j in xrange(0,500,100):
            #I change brightness of the images, just to emphasise they are unique copies.
            im=Image.eval(im,lambda x: x+(i+j)/30)
            #paste the image at location i,j:
            new_im.paste(im, (i,j))
    
    new_im.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多