from PIL import Image
sizes = [(120,120), (720,720), (1600,1600)]
files = ['a.jpg','b.jpg','c.jpg']
for image in files:
for size in sizes:
im = Image.open(image)
im.thumbnail(size)
im.save("thumbnail_%s_%s" % (image, "_".join(size)))
#!/bin/bash
start=$SECONDS
# Loop over all files
for f in image*.jpg; do
# Loop over all sizes
for s in 1600 720 120; do
echo Reducing $f to ${s}x${s}
convert "$f" -resize ${s}x${s} t-$f-$s.jpg
done
done
echo Time: $((SECONDS-start))
#!/bin/bash
start=$SECONDS
# Loop over all files
N=1
for f in image*.jpg; do
echo Resizing $f
# Load once and successively scale down
convert "$f" \
-resize 1600x1600 -write t-$N-1600.jpg \
-resize 720x720 -write t-$N-720.jpg \
-resize 120x120 t-$N-120.jpg
((N=N+1))
done
echo Time: $((SECONDS-start))
#!/bin/bash
start=$SECONDS
doit() {
file=$1
index=$2
convert "$file" \
-resize 1600x1600 -write t-$index-1600.jpg \
-resize 720x720 -write t-$index-720.jpg \
-resize 120x120 t-$index-120.jpg
}
# Export doit() to subshells for GNU Parallel
export -f doit
# Use GNU Parallel to do them all in parallel
parallel doit {} {#} ::: *.jpg
echo Time: $((SECONDS-start))
结果:18秒
方法4-GNU并行+VIP
这与前面的方法相同,但它在命令行使用vips,而不是ImageMagick。
#!/bin/bash
start=$SECONDS
doit() {
file=$1
index=$2
r0=t-$index-1600.jpg
r1=t-$index-720.jpg
r2=t-$index-120.jpg
vipsthumbnail "$file" -s 1600 -o "$r0"
vipsthumbnail "$r0" -s 720 -o "$r1"
vipsthumbnail "$r1" -s 120 -o "$r2"
}
# Export doit() to subshells for GNU Parallel
export -f doit
# Use GNU Parallel to do them all in parallel
parallel doit {} {#} ::: *.jpg
echo Time: $((SECONDS-start))
结果:8秒
方法5-顺序PIL
这是为了符合雅各布的回答。
#!/usr/local/bin/python3
import glob
from PIL import Image
sizes = [(120,120), (720,720), (1600,1600)]
files = glob.glob('image*.jpg')
N=0
for image in files:
for size in sizes:
im=Image.open(image)
im.thumbnail(size)
im.save("t-%d-%s.jpg" % (N,size[0]))
N=N+1
#!/usr/local/bin/python3
import cv2
import glob
from multiprocessing import Pool
def thumbnail(params):
filename, N = params
try:
# Load just once, then successively scale down
im = cv2.imread(filename)
im = cv2.resize(im, (1600,1600))
cv2.imwrite("t-%d-1600.jpg" % N, im)
im = cv2.resize(im, (720,720))
cv2.imwrite("t-%d-720.jpg" % N, im)
im = cv2.resize(im, (120,120))
cv2.imwrite("t-%d-120.jpg" % N, im)
return 'OK'
except Exception as e:
return e
files = glob.glob('image*.jpg')
pool = Pool(8)
results = pool.map(thumbnail, zip(files,range((len(files)))))
这个问题有点晚了(才一年!),但我将支持@JakobBowyer回答的“多进程it”部分。
这是embarrassingly parallel问题的一个很好的例子,因为代码的主要部分不会改变自身外部的任何状态。它只需读取输入,执行计算并保存结果。
由于
multiprocessing.Pool
提供的map函数,Python实际上非常擅长处理这些问题。代码的核心与@JakobBowyer完全相同,但是我们没有在一个线程中循环运行它,而是将它包装在一个函数中,通过多处理映射函数将它分布在多个核心上。
你想让它轻而易举地做到这一点
如果你急需速度。然后对其进行线程处理、多处理或获取另一种语言。
我喜欢一些乐趣,所以我做了一些基准的各种方法建议以上和我自己的一些想法。
我收集了1000张高分辨率的12MP iPhone6S图像,每个图像为4032x3024像素,并使用了8核iMac。
这里是技术和结果-每个在它自己的部分。
方法1-顺序图像处理
这是一个简单的、未经优化的代码。读取每个图像并生成缩略图。然后再次读取,并生成不同大小的缩略图。
结果:170秒
方法2-单次加载和连续调整大小的顺序图像图像处理
这仍然是循序渐进的,但稍微聪明一点。每个图像只读取一次,然后将加载的图像缩小三次并以三种分辨率保存。改进之处在于,每个图像只读取一次,而不是3次。
结果:76秒
方法3-GNU Parallel+ImageMagick
这是在前面方法的基础上,通过使用GNU Parallel并行处理
N
图像,其中N
是计算机上的CPU核心数。结果:18秒
方法4-GNU并行+VIP
这与前面的方法相同,但它在命令行使用
vips
,而不是ImageMagick。结果:8秒
方法5-顺序PIL
这是为了符合雅各布的回答。
结果:38秒
方法6-单次加载和连续调整大小的顺序PIL
这是对Jakob的回答的一个改进,在Jakob的回答中,图像只加载一次,然后向下调整三次大小,而不是每次重新加载以产生每个新的分辨率。
结果:27秒
方法7-并行PIL
这与Audionautics的答案相对应,因为它使用Python的多处理。它还避免了为每个缩略图大小重新加载图像的需要。
结果:6秒
方法8-并行OpenCV
这是为了改进bcattle的答案,因为它使用OpenCV,但也避免了重新加载图像以生成每个新的分辨率输出的需要。
结果:5秒
相关问题 更多 >
编程相关推荐