Php-exec命令转换图像


Php exec command to convert an image

我正在尝试使用imagemagik命令"convert"从.png图像创建.tif图像。

我带来的是:

$exec = "/opt/local/bin/convert -adaptive-resize 150% ".$pos.".png ".$pos.".tif";
exec($exec);

如果我运行到CLI"which convert",我会得到路径:/opt/local/bin/convert。我也尝试过不使用路径,只有/opt/local/bin/convert -adaptive-resize 150% ".$pos.".png ".$pos.".tif/etc/local/bin/convert -adaptive-resize 150% ".$pos.".png ".$pos.".tif

如果我在终端中运行该命令,它会按预期工作,但当我试图从PHP脚本中使用它时,它不会工作。

编辑:我还尝试过用以下代码创建一个.sh文件,但没有成功:

#! /bin/bash
convert -adaptive-resize 150% 1.png 1.tif
convert -adaptive-resize 150% 2.png 2.tif
convert -adaptive-resize 150% 3.png 3.tif
convert -adaptive-resize 150% 4.png 4.tif
convert -adaptive-resize 150% 5.png 5.tif
convert -adaptive-resize 150% 6.png 6.tif
convert -adaptive-resize 150% 7.png 7.tif
convert -adaptive-resize 150% 8.png 8.tif
convert -adaptive-resize 150% 9.png 9.tif

如果我从终端运行它,它就像一个符咒。相反,如果我尝试从一个简单的PHP文件执行它,它不会创建任何.tif文件。

<?php
$exec = "./convertpngtif.sh";
exec($exec);
?>

线索在上面的Hieu Nguyen回答中:当您使用PHP -r从命令行运行时,它可以工作。当你在浏览器中运行时,它不会。这导致了三个可能的问题之一。

需要记住的关键是,当您运行exec时,脚本、用户、路径和工作目录将使用与PHP运行时相同的用户/权限运行。

在命令行中运行PHP时,PHP将以用户身份("您")运行,因此exec()也将运行"您"。这也将是你用来编写shell脚本的同一个用户。因此,权限与你的权限相同,而且很有效(很棒)。

当PHP在Apache(或IIS)中运行时,可能是也可能不是"您"。在您的情况下,这显然不是因为脚本不起作用——PHP可能以"apache"、"http"或"www"或类似名称的用户的身份运行。

这导致了三个可能的问题之一。那么要检查什么:

1) 2)Path and工作目录。

上面建议一次一个,但更安全的做法是规定所有文件的绝对路径(即从根/开始的完整路径)——可执行命令、输入文件和输出文件。这排除了路径或工作目录中可能出现的任何差异。如果您使用shell脚本,请指定shell脚本的完整路径及其内部的完整路径(或在顶部设置路径/目录)

3) 权限

上面再次建议,但每个人都专注于文件。但是您检查过convert可执行命令本身的权限吗?

同样,对于shell脚本,您是否将其权限设置为PHP运行的用户的可执行权限?如果您在apache中以不同的用户身份运行,那么"您"拥有的rwxr--r是不令人满意的。

如果要解决这些问题,还有其他几个解决方案:

  1. 即使在Apache中使用fastCGI安装,也可以让PHP以"您"的身份运行。通过这种方式,您可以知道运行两个PHP脚本的用户/path/工作目录。(我仍然建议使用完整路径,但仍然可以缓解权限问题)

  2. 您可以通过以"apache"、"www"或"http"等身份登录并设置权限/路径来调试脚本,这样您的脚本现在就可以工作了。

考虑使用php-imagick而不是exec函数。

这对我来说像是一个权限问题。首先,你需要在终端上使用system()而不是exec()来调试你的php调用:

php -r 'system("/opt/local/bin/convert -adaptive-resize 150% 1.png 1.tif");'

我打赌你会看到确切的错误。我认为有两种情况:

  • 目标文件夹没有写入权限,在这种情况下,您可能需要将该文件夹的权限更改为777。

  • /opt/local/bin/convert没有执行权限,在这种情况下,您必须检查从/opt/opt/local等的每个文件夹权限,并至少授予每个文件夹755权限。

在这两种情况下,都可以使用ls -la获取每个文件夹的权限。

希望这能有所帮助。

我会使用PHP imagemagik的接口来实现这一点。类似这样的东西:

<?php
$image = new Imagick( "image.png" );
$height=$image->getImageHeight()*1.5; // 150% size
$width=$image->getImageWidth()*1.5;  // 150% size
$image->resizeImage( $width, $height,  imagick::FILTER_LANCZOS, 1 );
$image->setImageFormat( "tif" );
$image->writeImage( "image.tif" );
$image->clear(); 
$image->destroy(); 
?>

此答案适用于LINUX/MAC

我知道这是个老问题,但我也有类似的问题。执行shell命令而不出现路径问题的一种方法是创建一个新的登录shell使用

/bin/bash -l 

因此bash的行为就像一个登录shell,并且设置了所有的pathinfo。使用-c将命令添加为字符串

$exec = "/bin/bash -lc 'convert -adaptive-resize 150% ".$pos.".png".$pos.".tif'";
exec($exec,$out,$rcode);

你可以用这个来获得转换的路径

/bin/bash -lc 'which convert' 

并且在没有bash部分的情况下工作

仍然需要设置要转换的权限,并且php运行的用户可以登录。因此,/etc/passwd(ubuntu/debian)中的登录shell必须设置为

据我所知,您正在尝试使用ImageMagick来转换图像。

PHP有一个需要安装的Imagick库。如果你有root访问权限,你可以很容易地做到这一点,并使用imagick库包装器函数来转换图像(无需运行命令行)。

以下是php Imagick 的文档

您可以使用phpinfo();检查是否安装了imagick。

查看您是否具有正确的写入权限。

在linux中,Apache服务器的常见用户名是www数据

控制台中:

cd /var/www (or where you are saving your php files)
ls -la (You will see permissions)
sudo chown www-data:youruser thisfolder (change primary user to www-data and group to youruser)
sudo chmod 775 thisfilder (change permissions, write read exec for user and usergroup and read for others.

您也可以这样尝试在PHP:中执行shell脚本

<?php echo shell_exec('sh ./convertpngtif.sh');  ?>

<?php
$exec = file_get_contents("./convertpngtif.sh");
echo shell_exec($exec);
?>

我会通过首先打印错误消息来诊断错误:

$out, $ret;
$exec = "/opt/local/bin/convert -adaptive-resize 150% ".$pos.".png ".$pos.".tif 2>&1";
exec($exec, $out, $ret);
var_dump($out);

正如其他人所说,由于权限问题,imagemagik很可能停止从exec()运行,即使它可以从CLI正常运行。

如何使用临时目标文件

$source = dirname( __FILE__ ) . '/' . $pos.".png";
$target = tempnam( '/tmp/', 'tif-' );
rename( $target, $target . '.tif' );
$target .= '.tif';
$command = '/opt/local/bin/convert';
assert( file_exists( $command ));
assert( file_exists( $source ));
assert( is_readable( $source ));
assert( ! file_exists( $target ));
$exec = $command . " -adaptive-resize 150% ". escapeshellarg( $source ) . " " . escapeshellarg( $target );
exec( $exec );