【问题标题】:Python PIL efficienty glueing images together, while keeping image optimizationsPython PIL 有效地将图像粘合在一起,同时保持图像优化
【发布时间】:2021-03-19 10:39:25
【问题描述】:

TL;DR : 将 10mb 的图像连接成一张大图像时,在我将其保存/优化到磁盘之前,生成的图像是 1GB 的内存。如何使这个内存大小更小?

我正在做一个项目,我正在获取 Python Pil 图像对象(图像块)列表,并将它们粘合在一起:

  1. 生成已连接在一起的图像列表
  2. 选择 #1,并用所有图块制作完整的图像

This post 非常擅长提供通过

完成 1&2 的功能
  1. 确定最终图像大小
  2. 为要添加的图像创建空白画布
  3. 按顺序将所有图像添加到我们刚刚生成的画布中

但是,我遇到的代码问题:

  1. 列表列表中原始对象的大小约为 50mb。
  2. 当我对图像对象列表执行第一次操作时,生成的图像列表是列,内存增加了 1gb...当我制作最终图像时,内存又增加了 1gb。

由于生成的图像为 105,985 x 2560 像素...1gb 是有点预期的 ((105984*2560)*3 /1024 /1024) [~800mb]

我的预感是正在创建的画布未优化,因此占用了一些空间(像素 * 3 字节),但我尝试粘贴到画布上的图像平铺对象已针对大小。

因此我的问题是 - 使用 PIL/Python3,有没有更好的方法将图像连接在一起,保持它们的原始大小/优化?在我通过

处理图像/重新优化它之后
.save(DiskLocation, optimize=True, quality=94)

生成的图像约为 30 MB(大致相当于包含 PIL 对象的原始列表的大小)

作为参考,从上面链接的帖子中,这是我用来将图像连接在一起的函数:

from PIL import Image

#written by teekarna
# https://stackoverflow.com/questions/30227466/combine-several-images-horizontally-with-python

def append_images(images, direction='horizontal',
                  bg_color=(255,255,255), aligment='center'):
    """
    Appends images in horizontal/vertical direction.

    Args:
        images: List of PIL images
        direction: direction of concatenation, 'horizontal' or 'vertical'
        bg_color: Background color (default: white)
        aligment: alignment mode if images need padding;
           'left', 'right', 'top', 'bottom', or 'center'

    Returns:
        Concatenated image as a new PIL image object.
    """
    widths, heights = zip(*(i.size for i in images))

    if direction=='horizontal':
        new_width = sum(widths)
        new_height = max(heights)
    else:
        new_width = max(widths)
        new_height = sum(heights)

    new_im = Image.new('RGB', (new_width, new_height), color=bg_color)


    offset = 0
    for im in images:
        if direction=='horizontal':
            y = 0
            if aligment == 'center':
                y = int((new_height - im.size[1])/2)
            elif aligment == 'bottom':
                y = new_height - im.size[1]
            new_im.paste(im, (offset, y))
            offset += im.size[0]
        else:
            x = 0
            if aligment == 'center':
                x = int((new_width - im.size[0])/2)
            elif aligment == 'right':
                x = new_width - im.size[0]
            new_im.paste(im, (x, offset))
            offset += im.size[1]

    return new_im

【问题讨论】:

  • 您没有包含您的图片。请注意mmilli 的SI 前缀,而Mmega 的前缀。同样bbit 的缩写,而Bbyte 的缩写,使您的50mb 等于50 毫比特。
  • 请注意,您不需要编写任何 Python 来并排附加 N 个图像,您可以在终端中使用 ImageMagick 像这样 @987654333 @ 您可以使用magick -gravity north ...magick -gravity center ... 控制对齐,并使用-background magenta 设置未覆盖区域的背景。
  • 嗨,马克,感谢您的回复。不幸的是,我无法共享图像,并且需要在 python 脚本中运行此代码,每小时多次(所以没有命令行)。但是,我能够解决这个问题......不知道如何或为什么,但在开始时重新调整原始图像的大小,导致胶合过程中图像的大小与我预期的一样。

标签: python-3.x image image-processing python-imaging-library


【解决方案1】:

虽然我无法解释导致我失控的内存问题的原因,但我能够添加一些似乎已经解决问题的代码。

对于我试图粘合在一起的每个图块,我运行了一个“调整大小”脚本(如下)。不知何故,这解决了我遇到的问题 ¯\ (ツ)

调整图片大小脚本:

def resize_image(image, ImageQualityReduction = .78125):
    #resize image, by percentage
    width, height = image.size
    #print(width,height)
    new_width =  int(round(width * ImageQualityReduction))
    new_height = int(round(height * ImageQualityReduction))
    resized_image =  image.resize((new_width, new_height), Image.ANTIALIAS)
    return resized_image#, new_width, new_height

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-30
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 2010-11-17
    • 2021-05-26
    相关资源
    最近更新 更多