- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试批量处理文件夹内包含的图像,以调整其大小并优化它们以供在线使用。
以下脚本有效,但我必须运行两次才能获得所需的输出。这就是我期望它的工作方式:
将目标文件夹中的每个图像调整为特定大小,将“_small.png”添加到文件名中,并将其作为新文件保存在子文件夹“optimized_images”中,该子文件夹与原始图像组在同一目录中创建图片。
将新制作的图像放入“optimized_images”(“_small.png”)中,并应用减小原始文件大小的转换,添加“-opt.png”后缀以表明它已经过优化。
获取不再需要的函数 1 构建的文件(因为它们已被优化)并删除它们,以减少困惑。
当我运行脚本时,我从 function1 得到了预期的响应,目标文件中的所有文件都被适当调整大小并保存在“optimized_images”文件夹中。但我必须在函数2和3生效之前再次运行该脚本。它确实有效,但我以前从未遇到过这样的问题。知道为什么会发生这种情况吗?
我认为这可能与文件打开/关闭操作有关,但我认为我会在适当的时间将它们全部关闭。我将 Image.open 语法替换为使用“with Image.open(path) as image:”,但这并没有解决问题。
我认为 os.listdir 或 os.path 可能存在一些问题,可能必须“重置”才能遍历文件目录两次,但我找不到任何内容。
from PIL import Image
import os, sys
path = "../path/to/images/"
new_folder = '/optimized_images/'
optimized_path = path + new_folder[1:]
dirs = os.listdir( path )
optimized_dirs = os.listdir( optimized_path )
def resize_aspect_fit(final_size=250, dirs=dirs, optimized_path=optimized_path, optimized_dirs=optimized_dirs):
for item in dirs:
if item == '.DS_Store':
continue
if os.path.isfile(path+item):
with Image.open(path+item) as im:
f, e = os.path.splitext(path+item)
size = im.size
ratio = float(final_size) / max(size)
new_image_size = tuple([int(x*ratio) for x in size])
im = im.resize(new_image_size, Image.ANTIALIAS)
new_im = Image.new("RGBA", (final_size, final_size), color=(255,255,255,0))
new_im.paste(im, ((final_size-new_image_size[0])//2, (final_size-new_image_size[1])//2))
new_path, new_filename = f.rsplit('/', 1)
new_im.save(new_path + new_folder + new_filename + '_small.png', 'PNG', quality=10, optimize=True)
new_im.close()
def png_conversion(optimized_dirs=optimized_dirs, optimized_path=optimized_path):
for item in optimized_dirs:
if item == '.DS_Store':
continue
f, e = os.path.splitext(optimized_path+item)
with Image.open(f + e) as im:
im.load()
# Get the alpha band
alpha = im.split()[-1]
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
# Set all pixel values below 128 to 255,
# and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
# Paste the color of index 255 and use alpha as a mask
im.paste(255, mask)
# The transparency index is 255
e = e.split('.png')[0]
im.save(f + e + "-opt.png", transparency=255)
im.close()
def unoptimized_cleanup(optimized_dirs=optimized_dirs, optimized_path=optimized_path):
for item in optimized_dirs:
if item.endswith('small.png'):
os.remove(os.path.join(optimized_path, item))
#functions called in order
resize_aspect_fit(final_size=250, dirs=dirs)
png_conversion(optimized_dirs=optimized_dirs, optimized_path=optimized_path)
unoptimized_cleanup(optimized_dirs=optimized_dirs, optimized_path=optimized_path)
我希望对于以下文件夹结构:
folder/image1.png
folder/image2.png
输出应如下所示,具有适当大小和较小的文件:
folder/optimized_images/image1_small-opt.png
folder/optimized_images/image2_small-opt.png
我提取的相关来源:
Converting PNG32 to PNG8 with PIL while preserving transparency
Python/PIL Resize all images in a folder
最佳答案
问题是您在运行步骤 1 之前创建了变量 optimized_dirs
。因此,在执行步骤 1 之前,您在该目录中创建了一个文件列表,此时该目录为空。如果您第二次运行它,这些文件将位于 optimized_dirs
中,因此它可以工作。
解决方案是读取函数 png_compression
内 optimized_dirs
的内容,即将 os.listdir(optimized_path )
移动到其中。
顺便说一句:我发现您使用了一些魔法来构建路径,其中使用 [1:]
来防止双斜杠。使用 os.path.join 构建路径更加健壮,这将确保目录之间始终有一个斜杠,无论您是在每个目录的开头还是结尾指定它们。
关于python - 为什么我必须运行这个 python 脚本两次才能正确格式化图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56470781/
我正在从事的项目需要使用 toString 方法打印银行帐户余额。我不允许向当前程序添加任何方法,但我需要将 myBalance 变量格式化为 double 型,该变量保留两位小数而不是一位。在这个特
我喜欢 Visual Studio (2008) 格式化 C# 代码的方式;不幸的是,在编写 C++ 代码时,它的行为方式似乎有所不同。 比如我这样写代码的时候: class Test { publi
Scanner scan = new Scanner(System.in); System.out.println("Enter three positive integers seperated b
在 aspose(使用 C#)中用于格式化数字的正确样式属性是什么。我想做两件事: 1) 将五位数字格式化为邮政编码。(我不太确定使用哪个 Style 属性来获取自定义 excel 邮政编码格式) 2
我希望用户输入从 00 到 23 和从 00 到 59 的 Local.Time 的小时和分钟,我将其扫描为一个 int。它有效,但对于从 00 到 09 的值,int 忽略 0,然后将其放置为 0,
大家好, 请查看上面的图片,我有两张 table 。在下面代码的第一个表中,我得到了这种格式。 但我想像 Table2 那样格式化,每个合并单元格中的行数是动态的,而且不一样。 有没有办法像table
我在一个 laravel 网站工作,我只是想知道是否有办法为用户格式化 created_at 值,因为现在它类似于以下内容: 2017-09-20 13:41 但我更愿意将其格式化为易于阅读的格式,例
我正在尝试在 JTextPane 中进行一些基本的格式化。为此,我决定使用 html(HTMLDocument 和 HTMLEditorKit)。 这里是按钮的操作监听器代码,应使所选文本变为粗体 b
是否有规则或插件会导致 es-lint 错误或警告,如果范围内的声明没有像下面那样间隔,赋值运算符的对齐方式相同? var a = 'a'; var bb = 'b'; var ccc = 'd
我正在尝试重新格式化 LinkedHashMap 的输出以排除逗号和大括号。 这是我的看跌期权: token.put("[Server.Protocol]", url.getProtocol() +
我有一个程序,可以从文本文件中读取大量文本,然后根据文本内容随机化内容以显示为短篇故事。该程序可以运行,但最后一部分(我显示的 Material )非常笨重且效率不高,我想知道是否有人对如何更有效地获
我正在尝试将 VIM 作为我的 ruby/rails 编辑器。太胖了,我对它的功能印象深刻 并且我能够安装以下插件以提供更好的 IDE 体验 自动配对 Better-snipmate-snippe
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我有两个 jQuery 函数。我想先运行下面的第一个,然后在该函数完成后运行另一个。通常我会在代码的第一部分添加一个函数,但不确定如何使用这个 block 来做到这一点,或者它是否是正确的方法。 简而
在 Python 2.7 中,我有一个包含数字 1-25 字符串的列表(例如)。打印它们时,我希望列表打印 5 行,每行 5 个数字。 理想情况下: >>> print(myList) ['1', '
我有以下功能来打印借阅者已取出的书籍列表。 void searchBorrowerLoans(int a) { int i; for (i = 1
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 5 年前。 Improv
我正在尝试实现一个用作 ListView header 的 TextView。我想对其进行格式化,以便我基本上有一个以第一行为中心的标题,然后是以下几行的附加信息。如何格式化文本/字符串以创建这种格式
我尝试格式化数字字段 select to_char(12315.83453, 'FM999999999999D9999') 在这种情况下一切正常。结果是 12315.8345 但是如果值在0到1之间
我有一个带有 BigDecimal 字段的类。我把这个对象放到 JSP(Spring MVC)中。而且我需要显示十进制不带零的 BigDecimal 字段(20.00 就像 20),这就是为什么我的
我是一名优秀的程序员,十分优秀!