Php 如何加速复杂的图像处理?
每个用户都可以上传100张TIFF(黑白)图像 该过程需要:Php 如何加速复杂的图像处理?,php,image,imagemagick,converter,imagemagick-convert,Php,Image,Imagemagick,Converter,Imagemagick Convert,每个用户都可以上传100张TIFF(黑白)图像 该过程需要: real 0m6.806s user 0m37.582s sys 0m6.642s real 1m4.225s user 0m51.577s sys 0m8.247s 将tif转换为jpg 将图像大小调整为xx 将图像裁剪到200px 添加文本水印 以下是我的PHP代码: move_uploaded_file($image_temp,$destination_folder.$image_name);
real 0m6.806s
user 0m37.582s
sys 0m6.642s
real 1m4.225s
user 0m51.577s
sys 0m8.247s
tif
转换为jpg
move_uploaded_file($image_temp,$destination_folder.$image_name);
$image_name_only = strtolower($image_info["filename"]);
$name=$destination_folder.$image_name_only.".jpg";
$thumb=$destination_folder."thumb_".$image_name_only.".jpg";
$exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$destination_folder.$image_name. ' '.$name.' 2>&1';
exec($exec, $exec_output, $exec_retval);
$exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. ' -resize 1024x '.$name;
exec($exec, $exec_output, $exec_retval);
$exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. ' -thumbnail 200x200! '.$thumb;
exec($exec, $exec_output, $exec_retval);
$exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. " -background White label:ش.پ12355 -append ".$name;
exec($exec, $exec_output, $exec_retval);
这个代码有效。但每个图像的平均处理时间为1秒。
因此,对于100张图像,可能需要大约100秒
如何加快整个过程(转换、调整大小、裁剪、水印)
编辑
我有一台服务器G8:Ram:32G,CPU:Intel Xeon E5-2650(4进程) 版本:ImageMagick 6.9.0-3 Q16 x64 特点:OpenMP 资源限制: 宽度:100MP;高度:100MP;面积:17.16GP;内存:7.9908GiB;Map:15.982GiB;磁盘:无限制;档案:1536;线程:8;节流阀:0;时间:无限期 0两种方法 基本上,这一挑战可以通过两种不同的方式来解决,或者两者结合:
convert -version
如果您的ImageMagick在其版本字符串中有Q16
(甚至Q32
或Q64
,这是可能的,但有点过头了!):
这意味着,ImageMagick的所有内部函数都将所有图像视为具有16位(或32位或64位)通道深度。
这将为您提供更好的图像处理质量。
但与Q8相比,它也需要两倍的内存。
因此,这同时意味着性能下降
因此:您可以通过切换到Q8
-build来测试您将获得哪些性能优势。
(Q是ImageMagick构建支持的“量子深度”的符号。)
您将支付可能的Q8
——性能提高但质量降低。
只需检查一下您在Q8
上比Q16
取得的速度,以及您遭受的质量损失。
然后决定你是否能忍受这些缺点
在任何情况下,Q16
将使用两倍于每个图像的RAM进行处理,而Q32
将再次使用两倍于Q16
的RAM。
这与输入文件中每像素的实际位数无关。
16位图像文件在保存时也会比8位文件占用更多的磁盘空间
由于Q16
或Q32
需要更多内存,您必须始终确保有足够的内存。
因为超过你的物理内存将是一个非常坏的消息。
如果一个较大的Q
将进程交换到磁盘,性能将急剧下降。
1074 x 768
像素图像(width x height
)将需要以下数量的虚拟内存,具体取决于量子深度:
Quantum Virtual Memory
Depth (consumed by 1 image 1024x768)
------- ------------------------------
8 3.840 kiB (=~ 3,75 MiB)
16 7.680 kiB (=~ 7,50 MiB)
32 15.360 kiB (=~ 14,00 MiB)
还要记住,一些“优化”的处理管道(见下文)将需要在虚拟内存中保留图像的多个副本!
一旦可用RAM无法满足虚拟内存的需求,系统将开始交换并从磁盘中声明“内存”。
在这种情况下,所有聪明的命令管道优化当然都消失了,并开始转向相反的方向
ImageMagick的生日在aera,当时CPU一次只能处理1位数据。
那是几十年前的事了。
从那时起,CPU体系结构发生了很大的变化。
16位操作的时间是8位操作的两倍,甚至更长。
然后16位处理器出现了。
16位操作成为标准。
CPU优化为16位:
突然间,某些8位操作可能需要比16位等效操作更长的时间
如今,64位CPU很常见。
因此,Q8
vs.Q16
vs.Q32
实数参数甚至可能无效。
谁知道呢?
我不知道有任何关于这方面的严肃基准测试。
如果有一天有人(对CPU和基准测试现实世界的程序有很深的了解)会运行这样一个项目,那将是很有趣的
是的,我看到您正在Windows上使用Q16。
但为了完整起见,我还是想提一下。。。
将来会有其他用户阅读此问题和给出的答案
很有可能,由于您的输入TIFF仅为黑白,因此Q8
构建的图像质量输出足以满足您的工作流程。
(我只是不知道它是否会更快:
这在很大程度上还取决于运行此功能的硬件资源…)
此外,如果您的安装支持HDRI
(高动态分辨率图像),这也可能会导致一些速度损失。
谁知道呢?
因此,使用configure options——disable hdri——quantum depth 8
构建IM可能会也可能不会带来速度提升。
从来没有人认真地测试过这个。。。
关于这一点,我们只知道:
这些选项将降低图像质量。
然而,大多数人甚至不会注意到这一点,除非他们真的仔细观察,并进行直接的图像对比
2.检查ImageMagick的功能
接下来,检查ImageMagick安装是否附带和/或支持:
如果它是(像我的一样),你应该看到这样的东西:
FEATURES DPC HDRI OpenCL OpenMP Modules
identify -list resource
File Area Memory Map Disk Thread Time
--------------------------------------------------------------------
192 4.295GB 2GiB 4GiB unlimited 1 unlimited
OpenCL(用于C计算L语言)利用ImageMagick的并行计算功能(如果在中编译)。
这将利用计算机的GPU和CPU进行图像处理操作
OpenMP(用于Multi-p处理)执行类似的操作:
它允许ImageMagick在系统的所有核心上并行执行。
因此,如果您有一个四核系统,并调整图像的大小,调整大小发生在4核(甚至8,如果您有超线程)
命令
convert -version
印刷品
convert logo: -resize 500% -bench 10 logo.png
[....]
Performance[4]: 10i 1.489ips 1.000e 6.420u 0:06.510
identify -list resource
File Area Memory Map Disk Thread Time
--------------------------------------------------------------------
384 8.590GB 4GiB 8GiB unlimited 4 unlimited
identify -list resource
File Area Memory Map Disk Thread Time
--------------------------------------------------------------------
192 4.295GB 2GiB 4GiB unlimited 1 unlimited
convert -limit thread 2
convert input.jpeg input.mpc
convert input.mpc [...your long-long-long list of crops and operations...]
convert image.tiff image.jpg
convert image.jpg -resize 1024x image-1024.jpg
convert image-1024.jpg -thumbnail 200x200 image-thumb.jpg
convert -background white image-1024.jpg label:12345 -append image-labelled.jpg
convert image.tiff \
-respect-parentheses \
+write mpr:XY \
\( mpr:XY +write image-1024.jpg \) \
\( mpr:XY -thumbnail 200x200 +write image-thumb.jpg \) \
\( mpr:XY -background white label:12345 -append +write image-labelled.jpg \) \
null:
time for i in $(seq -w 1 100); do
convert image.tiff \
image-indiv-run-${i}.jpg
convert image-indiv-run-${i}.jpg -sample 1024x \
image-1024-indiv-run-${i}.jpg
convert image-1024-indiv-run-${i}.jpg -thumbnail 200x200 \
image-thumb-indiv-run-${i}.jpg
convert -background white image-1024-indiv-run-${i}.jpg label:12345 -append \
image-labelled-indiv-run-${i}.jpg
echo "DONE: run indiv $i ..."
done
real 0m49.165s
user 0m39.004s
sys 0m6.661s
time for i in $(seq -w 1 100); do
convert image.tiff \
-respect-parentheses \
+write mpr:XY \
\( mpr:XY -resize 1024x \
+write image-1024-pipel-run-${i}.jpg \) \
\( mpr:XY -thumbnail 200x200 \
+write image-thumb-pipel-run-${i}.jpg \) \
\( mpr:XY -resize 1024x \
-background white label:12345 -append \
+write image-labelled-pipel-run-${i}.jpg \) \
null:
echo "DONE: run pipeline $i ..."
done
real 0m29.128s
user 0m28.450s
sys 0m2.897s
time for i in $(seq -w 1 100); do
convert image.tiff \
-respect-parentheses \
\( -clone 0 -thumbnail 200x200 \
+write image-thumb-pipel-run-${i}.jpg \) \
\( -clone 0 -resize 1024x \
-background white label:12345 -append \
+write image-labelled-pipel-run-${i}.jpg \) \
null:
echo "DONE: run pipeline $i ..."
done
real 0m19.432s
user 0m18.214s
sys 0m1.897s
time for i in $(seq -w 1 100); do
convert image.tiff \
-respect-parentheses \
\( -clone 0 -thumbnail 200x200 \
+write image-thumb-pipel-run-${i}.jpg \) \
\( -clone 0 -scale 1024x \
-background white label:12345 -append \
+write image-labelled-pipel-run-${i}.jpg \) \
null:
echo "DONE: run pipeline $i ..."
done
real 0m16.551s
user 0m16.124s
sys 0m1.567s
time for i in $(seq -w 1 100); do
convert image.tiff \
-respect-parentheses \
\( -clone 0 -thumbnail 200x200 -depth 8 \
+write d08-image-thumb-pipel-run-${i}.jpg \) \
\( -clone 0 -scale 1024x -depth 8 \
-background white label:12345 -append \
+write d08-image-labelled-pipel-run-${i}.jpg \) \
null:
echo "DONE: run pipeline $i ..."
done
time for i in $(seq -w 1 100); do \
cat <<EOF
convert image.tiff \
\( -clone 0 -scale 1024x -depth 8 \
-background white label:12345 -append \
+write d08-image-labelled-pipel-run-${i}.jpg \) \
\( -clone 0 -thumbnail 200x200 -depth 8 \
+write d08-image-thumb-pipel-run-${i}.jpg \) \
null:
echo "DONE: run pipeline $i ..."
EOF
done | parallel --will-cite
real 0m6.806s
user 0m37.582s
sys 0m6.642s
time for i in $(seq -w 1 100); do
cat <<EOF
convert image.tiff \
-respect-parentheses \
+write mpr:XY \
\( mpr:XY -resize 1024x \
+write image-1024-pipel-run-${i}.jpg \) \
\( mpr:XY -thumbnail 200x200 \
+write image-thumb-pipel-run-${i}.jpg \) \
\( mpr:XY -background white label:12345 -append \
+write image-labelled-pipel-run-${i}.jpg \) \
null:
echo "DONE: run pipeline $i ..."
EOF
done | parallel
#!/bin/bash
for i in $(seq -w 1 100); do
echo ffmpeg -y -loglevel panic -i image.tif ff-$i.jpg
echo ffmpeg -y -loglevel panic -i image.tif -vf scale=1024:682 ff-$i-1024.jpg
echo ffmpeg -y -loglevel panic -i image.tif -vf scale=200:200 ff-$i-200.jpg
done | parallel
time for i in $(seq -w 1 100); do
gm convert image.tiff gm-${i}-image.jpg
gm convert gm-${i}-image.jpg -resize 1024x gm-${i}-image-1024.jpg
gm convert gm-${i}-image-1024.jpg -thumbnail 200x200 gm-${i}-image-thumb.jpg
gm convert -background white \
gm-${i}-image-1024.jpg label:12345 -append gm-${i}-image-labelled.jpg
echo "GraphicsMagick run no. $i ..."
done
real 1m4.225s
user 0m51.577s
sys 0m8.247s
#!/bin/bash
for file in $*; do
convert $file \
-respect-parentheses \
\( -clone 0 -resize 200x200 \
+write $file-thumb.jpg \) \
\( -clone 0 -resize 1024x \
-background white label:12345 -append \
+write $file-labelled.jpg \) \
null:
done
#!/usr/bin/python
import sys
from gi.repository import Vips
for filename in sys.argv[1:]:
im = Vips.Image.new_from_file(filename, access = Vips.Access.SEQUENTIAL)
im = im.resize(1024.0 / im.width)
mem = Vips.Image.new_memory()
im.write(mem)
thumb = mem.resize(200.0 / mem.width)
thumb.write_to_file(filename + "-thumb.jpg")
txt = Vips.Image.text("12345", dpi = 72)
footer = txt.embed(10, 10, mem.width, txt.height + 20)
mem = mem.join(footer, "vertical")
mem.write_to_file(filename + "-labelled.jpg")
$ time ../im-bench.sh *
real 0m32.033s
user 1m40.416s
sys 0m3.316s
$ time ../vips-bench.py *
real 0m22.559s
user 1m8.128s
sys 0m1.304s