1

proc_open() php 関数を使用するときに、プロセスにパイプされるストリームの使用に問題があるようです。

私が始めようとしているプロセスは、3 つの画像を重ね合わせて作成するための単純な変換 ImageMagick ユーティリティです。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 構文は、fd:N のような代替 io ストリームを指定します。ここで、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 パイプの内容を転送できないようです

4

1 に答える 1

1

私が決めた解決策は、生成された3つの画像を1つのphp変数に連結することでした。したがって、各画像出力は次の画像に連結されます。後でproc_open()が呼び出されたときに、変換入力ストリームにSTDINのみを割り当てます(入力ファイルデータ、つまり連結された画像変数を保持します)。私が使用している形式はpngで、そのような積み重ねられた画像ではうまく機能するようです。pngを指定するたびに:-入力用の変換コマンドで、次の画像がプルされ、入力として使用されます。このようにして、1つの変数から3つの画像すべての画像データを提供できます。

このソリューションは、Imagemagickで可能であると文書化されている番号付きファイル記述子fd:Nの単なる代替手段です。それはタスクを実行しますが、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);
         }

.................................................。 .................................。

于 2012-04-06T10:07:31.133 に答える