Why does this basic imagejpeg() resizer returns a black image?

白昼怎懂夜的黑 提交于 2020-01-04 04:07:04

问题


EDIT

Thanks for all your answers, especially @Mailerdaimon who noticed that I wasn't using the computed values in the imagecopyresampled function.

I don't get black images anymore, but i still do get some black part so i figure my ratio formula should be updated : if i upload a landscape image, the height of the new image is smaller than 170px, and then there's some black showing.

How can i make sure the height of the image goes all the way ?


Below is a simple script to allow users upload pictures. Once the upload is done, the pictures are displayed as a 170px(h) x 150px(w) thumbnail.

The resize part does work since the output image is 170x150px BUT i still get some black area if

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'"); 

        } 
  }

Any idea what I'm doing wrong?


回答1:


I never used php, so this might not be correct, but i can´t see where you use your computed values for width and height!

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);
     }

here you compute the height and width and after that they dont appear anywhere in your code...

EDIT: You use:

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

But the Documentation of imagecopyresmapled states that the function takes the follow

imagecopyresampled ($dst_image ,$src_image ,$dst_x ,$dst_y ,$src_x ,$src_y ,$dst_w , $dst_h ,$src_w ,$src_h )

Though i think your code should be

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

as already mentioned by @Manolo Salsas (and several others)

EDIT2: another problems lies in how you compute your Heigth and Width Values. if $height gets computed likes this

$height = floor($width * $originalHeight / $originalWidth);

it can be smaller than $maxHeight, though creating a black (unfilled) area in your Resulting image, as you have created this image using the max values

$image_p = imagecreatetruecolor($maxWidth, $maxHeight);

To fix this use your computed $thumbnail_height and $thumbnail_width values to create the image

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

or always resize your image to the max values

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

which may distort the image. If you dont want to distort the image think about resizing first such that on size fits in the thumbnail and then crop the longer side.




回答2:


  1. Be sure the folder "uploads" is writable or owned by the Web Server
  2. Try using a absolute path: /var/www/mysite/uploads
  3. Try to use something different to a random id, like a hash or md5 of the row ID or the image itself to avoid duplicity.

You can change the last part:

...

$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'"); }

...




回答3:


First of all,

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

This function checks if the file is a real image (not just the extension). If the file is not an image, it will return false (and a warning, that's why the at).

If the file is a real image can return this if you want:

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

or just the size:

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

So if you are using this function, remember to add the at, and use an if condition to check if you are receiving a real image.

On the other hand, after validate that you are receiving a real image and smaller than the size you want, you can do:

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

where $imagePath is the path where you want to safe the image.

Then, you can do:

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

And you'll have the right image resized.



来源:https://stackoverflow.com/questions/19551747/why-does-this-basic-imagejpeg-resizer-returns-a-black-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!