似乎我在使用proc_open()php函数时使用通过管道传输到流的流时遇到问题。
我开始的过程只是转换ImageMagick实用程序,将3个图像组合在一起。当只使用1个输入流(STDIN)并将变量转储到该流中时,转换程序正常工作并返回其输出,该输出可以存储在如下变量中:
$cmd = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$cmd .= ' -size SOMESIZE ';
$cmd .= ' -background black ';
$cmd .= ' -fill white ';
$cmd .= ' -stroke none ';
$cmd .= ' -gravity center ';
$cmd .= ' -trim ';
$cmd .= ' -interline-spacing SOMELINEHEIGHT ';
$cmd .= ' -font SOMEFONT ';
$cmd .= ' label:"SOMETEXT" ';
$cmd .= ' miff:- ';
$ctext_opacity = shell_exec($cmd);
首先,我运行转换并将输出存储在$ ctext_opacity变量中。然后通过proc_open()调用下一个命令,并将$ ctext_opacity变量通过STDIN传送并用作输入图像:
$cmd = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$cmd .= '-size SOMESIZE ';
$cmd .= ' xc:\'rgb(230, 225, 50)\' ';
$cmd .= ' -gravity center ';
$cmd .= ' - '; // ImageMagick uses dash(-) for STDIN
$cmd .= ' -alpha Off ';
$cmd .= ' -compose CopyOpacity ';
$cmd .= ' -composite ';
$cmd .= ' -trim ';
$cmd .= ' miff:- ';
$chighlight = '';
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $ctext_opacity);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$chighlight .= fgets($pipes[1]); // HERE WE FEED THE OUTPUT OF "CONVERT" TO $chighlight
}
//echo $chighlight; die();
fclose($pipes[1]);
$return_value = proc_close($process);
}
上述命令被调用3次,生成3个单独的图像并存储在3个变量中。下一个命令应该接受这3个变量作为输入图像(ImageMagic语法指定替代io流,如fd:N,其中N是我通过proc_open()生成的流的编号)。但是我似乎正在写入输入流或从STDOUT读取错误,这很可能导致进程的未刷新输出导致它挂起而不终止。
$cmd = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$cmd .= ' -size SOMESIZE ';
$cmd .= ' xc:transparent ';
$cmd .= ' -gravity center ';
$cmd .= ' - -geometry -2-2 -composite ';
$cmd .= ' fd:3 -geometry +2+2 -composite ';
$cmd .= ' fd:4 -composite ';
$cmd .= 'png:- ';
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "a"),
3 => array("pipe", "r"),
4 => array("pipe", "r")
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
$read = null;
$rd = array($pipes[1]);
$write = array($pipes[0], $pipes[3], $pipes[4]);
$wt = array($pipes[0], $pipes[3], $pipes[4]);
$im_args = array($cshade, $chighlight, $ctext);
$except = null;
$readTimeout = 1;
$ctext_deboss = '';
$numchanged = stream_select($read, $write, $except, $readTimeout);
foreach($write as $w) {
$key = array_search($w, $wt);
fwrite($wt[$key], $im_args[$key]);
fclose($wt[$key]);
$read = array($pipes[1]);
$rd = array($pipes[1]);
$write = null;
$except = null;
$readTimeout = 1;
$ctext_deboss = '';
$numchanged = stream_select($read, $write, $except, $readTimeout);
foreach($read as $r) {
while (!feof($r)) {
$ctext_deboss .= fgets($pipes[1]);
}
}
fclose($pipes[1]);
$return_value = proc_close($process);
echo $ctext_deboss; die();
}
}
我似乎无法转移3&转换为4个管道的内容会因空/错误数据而引发错误
答案 0 :(得分:1)
我解决的解决方案是在一个php变量中连接3个生成的图像。 因此每个图像输出连接到下一个。稍后当调用proc_open()时,仅为转换输入流分配STDIN(它将保存输入文件数据,即我们的连接图像var)。我正在使用的格式是png,它似乎与这样的堆叠图像一起正常工作。每次提供png时: - 在转换命令中输入下一个图像将被拉出并用作输入。这样,您就可以从单个变量中提供所有3个图像的图像数据。
该解决方案只是编号文件描述符fd:N的替代方法,记录在Imagemagick中是可能的。它确实完成了任务,但问题是为什么我用proc_open()设置并提供给Imagemagick转换的额外输入管道不起作用。
$khh = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$khh .= ' -size '.$imageSize.' ';
$khh .= ' xc:\'rgb(230, 225, 50)\' ';
$khh .= ' -gravity center ';
$khh .= ' - ';
$khh .= ' -alpha Off ';
$khh .= ' -compose CopyOpacity ';
$khh .= ' -composite ';
$khh .= ' -trim ';
$khh .= ' png:- ';
$chighlight = '';
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open($khh, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $ctext_opacity);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$chighlight .= fgets($pipes[1]);
}
fclose($pipes[1]);
$return_value = proc_close($process);
}
............................................... .....................................
$khh = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$khh .= ' -size '.$imageSize.' ';
$khh .= ' xc:'.$fontColor.' ';
$khh .= ' -gravity center ';
$khh .= ' - ';
$khh .= ' -alpha Off ';
$khh .= ' -compose CopyOpacity ';
$khh .= ' -composite ';
$khh .= ' -trim ';
if($_GET['ctr']==='3') {
$khh .= ' png:- ';
} else {
$khh .= ' png:- ';
}
$ctext = '';
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open($khh, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $ctext_opacity);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$ctext .= fgets($pipes[1]);
}
fclose($pipes[1]);
$return_value = proc_close($process);
}
............................................... .....................................
$khh = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$khh .= ' -size '.$imageSize.' ';
$khh .= ' xc:\'rgb(50, 85, 20)\' ';
$khh .= ' -gravity center ';
$khh .= ' - ';
$khh .= ' -alpha Off ';
$khh .= ' -compose CopyOpacity ';
$khh .= ' -composite ';
$khh .= ' -trim ';
$khh .= ' png:- ';
$cshade = '';
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open($khh, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $ctext_opacity);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$cshade .= fgets($pipes[1]);
}
fclose($pipes[1]);
$return_value = proc_close($process);
}
............................................... .....................................
$khh = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$khh .= ' -size '.$sizeX.'x'.$sizeY;
$khh .= ' xc:transparent ';
$khh .= ' -gravity center ';
$khh .= ' png:- -geometry -'.$i.'-'.$i.' -composite ';
$khh .= ' png:- -geometry +'.$i.'+'.$i.' -composite ';
$khh .= ' png:- -composite ';
$khh .= ' png:- ';
$ctext_deboss = '';
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open($khh, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $cshade.$chighlight.$ctext);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$ctext_deboss .= fgets($pipes[1]);
}
fclose($pipes[1]);
$return_value = proc_close($process);
}
............................................... .....................................