为什么这个基本的imagejpeg()缩放器返回黑色图像?

时间:2013-10-23 20:33:17

标签: php image image-processing upload gd

修改

感谢您的所有答案,特别是@Mailerdaimon注意到我没有使用imagecopyresampled函数中的计算值。

我不再获得黑色图像,但我仍然会得到一些黑色部分所以我认为我的比例公式应该更新:如果我上传风景图像,新图像的高度小于170像素,然后有一些黑色的表现。

如何确保图像的高度一直保持?


以下是允许用户上传图片的简单脚本。上传完成后,图片将显示为170px(h)x 150px(W)的缩略图。

调整大小部分可以正常工作,因为输出图像是170x150px但是如果

我还会得到一些黑色区域
if ($_SERVER["REQUEST_METHOD"] == "POST") 
{

$maxWidth  = 150;
$maxHeight = 170;

$name = $_FILES ['image'] ['name'];
$type = $_FILES ["image"] ["type"];
$size = $_FILES ["image"] ["size"];
$tmp_name = $_FILES ['image'] ['tmp_name'];
list($originalWidth, $originalHeight) = getimagesize($tmp_name);


 if ($originalWidth > $originalHeight) 
 {
   $thumbnail_height = floor(($originalHeight/$originalWidth)*$maxWidth);
   $thumbnail_width  = $maxWidth;
 } else {
   $thumbnail_width  = floor(($originalWidth/$originalHeight)*$maxHeight);
   $thumbnail_height = $maxHeight;
 }

 // Resample  
  $image_p = imagecreatetruecolor($maxWidth, $maxHeight);
  imagecreatefrompng($tmp_name);
  imagecopyresampled($image_p, 0, 0, 0, 0, $thumbnail_width, $thumbnail_height, 
  $originalWidth, $originalHeight);

//start upload process
$RandomNumber = uniqid();
$location = "uploads/$RandomNumber";
imagejpeg($image_p,  $location, 100);      

$sql=query("UPDATE users SET image = '".$location."' WHERE id = '$id'"); 

        } 
  }

知道我做错了吗?

3 个答案:

答案 0 :(得分:1)

  1. 确保“上传”文件夹可由Web服务器写入或拥有
  2. 尝试使用绝对路径:/ var / www / mysite / uploads
  3. 尝试使用与随机ID不同的内容,例如行ID的哈希值或md5或图像本身,以避免重复。
  4. 您可以更改最后一部分:

    ...

    $ RandomNumber = md5($ image_p); $ location =“/ var / www / mysite / uploads / $ RandomNumber”; if(imagejpeg($ image_p,$ location,100)){
       query(“UPDATE users SET image ='”。$ location。“'WHERE id ='$ id'”); }

    ...

答案 1 :(得分:1)

我从未使用过php,所以这可能不正确,但是我无法看到你在哪里使用宽度和高度的计算值!

if ($originalWidth > $maxWidth || $originalHeight > $maxHeight)
 {
      if ($originalWidth / $maxWidth > $originalHeight / $maxHeight) 
     {
       // width is the limiting factor
       $width = $maxWidth;
       $height = floor($width * $originalHeight / $originalWidth);

     } else { 
       // height is the limiting factor
       $height = $maxHeight;
       $width = floor($height * $originalWidth / $originalHeight);
     }

在这里你计算高度和宽度,之后它们不会出现在你的代码中的任何地方......

修改 你使用:

$image_p = imagecreatetruecolor($maxWidth, $maxHeight);
imagecreatefrompng($tmp_name);
imagecopyresampled($image_p, 0, 0, 0, 0, $thumbnail_width, $thumbnail_height,$originalWidth, $originalHeight);

imagecopyresmapled imagecopyresampled ($dst_image ,$src_image ,$dst_x ,$dst_y ,$src_x ,$src_y ,$dst_w , $dst_h ,$src_w ,$src_h ) 表示该函数采用了以下

imagecopyresampled($image_p,$tmp_name, 0, 0, 0, 0, $thumbnail_width, $thumbnail_height,$originalWidth, $originalHeight);

虽然我认为你的代码应该是

$height
正如@Manolo Salsas(以及其他几位)已经提到的那样

<强> EDIT2: 另一个问题在于如何计算Heigth和Width值。 如果计算$height = floor($width * $originalHeight / $originalWidth); 喜欢这个

$maxHeight

它可能小于$image_p = imagecreatetruecolor($maxWidth, $maxHeight); ,但在结果图像中创建了一个黑色(未填充)区域,因为您使用最大值创建了此图像

 $image_p = imagecreatetruecolor($thumbnail_width, $thumbnail_height);

要解决此问题,请使用您计算的$ thumbnail_height和$ thumbnail_width值来创建图像

imagecopyresampled($image_p,$tmp_name, 0, 0, 0, 0, $maxWidth, $maxHeight,$originalWidth, $originalHeight);

或始终将图片调整为最大值

{{1}}

可能会扭曲图像。如果您不想扭曲图像,请考虑首先调整大小,使大小适合缩略图,然后裁剪较长的一面。

答案 2 :(得分:0)

首先,

@getimagesize($_FILES['userfile']['tmp_name']))

此功能检查文件是否为真实图像(而不仅仅是扩展名)。如果文件不是图像,它将返回false(并发出警告,这就是at的原因。)

如果文件是真实图像,可以根据需要返回:

list($width, $height, $type, $attributes) = @getimagesize($_FILES['userfile']['tmp_name']))

或只是尺寸:

$size = @getimagesize($_FILES['userfile']['tmp_name']))

因此,如果您正在使用此功能,请记住添加at,并使用if条件检查您是否正在接收真实图像。

另一方面,在验证您收到的实际图像并且小于您想要的尺寸后,您可以执行以下操作:

if(move_uploaded_file($_FILES['userfile']['tmp_name'], $imagePath)

其中$imagePath是您要保护图片的路径。

然后,你可以这样做:

$image = imagecreatefromjpeg($imagePath);
$canvas=imagecreatetruecolor($maxwidth,$maxheight);
imagecopyresampled($canvas, $image ,0,0,0,0,$maxwidth, $maxheight, $originalWidth, $originalHeight);

并且您将调整正确的图像大小。