10

I need a way (using built-in PHP libs) to pull down an image from URL and save it to local disk with resized/scaled WIDTH to 150px. I have been trying this:

Creating a thumbnail from an uploaded image

function makeThumbnails($updir, $img, $id)
{
    $thumbnail_width = 134;
    $thumbnail_height = 189;
    $thumb_beforeword = "thumb";
    $arr_image_details = getimagesize("$updir" . $id . '_' . "$img"); // pass id to thumb name
    $original_width = $arr_image_details[0];
    $original_height = $arr_image_details[1];
    if ($original_width > $original_height) {
        $new_width = $thumbnail_width;
        $new_height = intval($original_height * $new_width / $original_width);
    } else {
        $new_height = $thumbnail_height;
        $new_width = intval($original_width * $new_height / $original_height);
    }
    $dest_x = intval(($thumbnail_width - $new_width) / 2);
    $dest_y = intval(($thumbnail_height - $new_height) / 2);
    if ($arr_image_details[2] == 1) {
        $imgt = "ImageGIF";
        $imgcreatefrom = "ImageCreateFromGIF";
    }
    if ($arr_image_details[2] == 2) {
        $imgt = "ImageJPEG";
        $imgcreatefrom = "ImageCreateFromJPEG";
    }
    if ($arr_image_details[2] == 3) {
        $imgt = "ImagePNG";
        $imgcreatefrom = "ImageCreateFromPNG";
    }
    if ($imgt) {
        $old_image = $imgcreatefrom("$updir" . $id . '_' . "$img");
        $new_image = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
        imagecopyresized($new_image, $old_image, $dest_x, $dest_y, 0, 0, $new_width, $new_height, $original_width, $original_height);
        $imgt($new_image, "$updir" . $id . '_' . "$thumb_beforeword" . "$img");
    }
}

That looks very promising but I can't figure out how to use it, and then whether it will do what I want. Concerns/needs:

  1. What do these params mean: ($updir, $img, $id) -- Is $updir the location of the file? Or the location where I want it saved? Is $img a file handle or the name of the file? Or the new name of the file? What is $id for? The author didn't give any sample usage.
  2. The function seems to require me to specify WIDTH and HEIGHT. I only want to specify WIDTH and let the height be proportional.
  3. I need to pull images over 2 different types of URL: (1) The basic http://foo..., and (2) the data syntax: data:image/jpeg;base64,/9j/4AAQ....
  4. Ideally I'd like to convert these images in all cases down to a compressed jpeg thumbnail (150px width, any height), even if the original image was not in jpg format.

What's the best way to accomplish this?

Community
  • 1
  • 1
HerrimanCoder
  • 6,835
  • 24
  • 78
  • 158
  • Well the script you posted looks like its bases on images upload to the server its running on where `$updir` would be the path to the directory containing them and `$id` and `$img` are part of the filename for some sort of naming convention. So in short this would only work once you have the files downloaded/copied. – prodigitalson Mar 06 '15 at 15:18
  • 1
    have a look at http://stackoverflow.com/a/27362839/3641016, I provided a small helper function to resize an image with different modes. – Raphael Müller Mar 06 '15 at 15:25
  • Raphael, you nailed it. Want to post your answer so I can give you the bounty? – HerrimanCoder Mar 07 '15 at 16:40
  • Check my answer below .. I use ImageCreateFromString which drops all the manual file detection since it is handled already internally by PHP. – flyandi Mar 13 '15 at 04:42

5 Answers5

39

Just do this:

function Thumbnail($url, $filename, $width = 150, $height = true) {

 // download and create gd image
 $image = ImageCreateFromString(file_get_contents($url));

 // calculate resized ratio
 // Note: if $height is set to TRUE then we automatically calculate the height based on the ratio
 $height = $height === true ? (ImageSY($image) * $width / ImageSX($image)) : $height;

 // create image 
 $output = ImageCreateTrueColor($width, $height);
 ImageCopyResampled($output, $image, 0, 0, 0, 0, $width, $height, ImageSX($image), ImageSY($image));

 // save image
 ImageJPEG($output, $filename, 95); 

 // return resized image
 return $output; // if you need to use it
}

Use it like this:

Thumbnail("http://cdn.cutestpaw.com/wp-content/uploads/2013/01/l-Cute-Kitten.jpg", "kitten.jpg");

The trick here is to use PHP's internal automatic file detection for the incoming stream which is very good handled by ImageCreateFromString

flyandi
  • 1,919
  • 16
  • 25
  • 3
    Andy, I awarded this to you because: (1) It works; (2) you didn't send me to 3rd-party libs; (3) it's minimalist; (4) you gave a working example of how to use it. Thanks for the perfect answer. – HerrimanCoder Mar 13 '15 at 12:22
  • yes it's worked nicely. do you now how to crop image by size to make thumbnails. – yussan Aug 27 '16 at 04:08
  • 1
    I wanted to thumbnail images even if the url was https and certificate invalid (generally self-signed) so had to incorporate https://stackoverflow.com/a/26151993/1238884 into the file_get_contents in this answer - otherwise, perfect for my needs. Cheers! – frumbert Jun 14 '17 at 04:04
  • BTW, the php manual shows imagecreatefromstring, imagecreatetruecolor, imagecopyresampled, imagejpeg, imagesx, imagesy all in lower case? – Meryan Mar 29 '20 at 21:51
  • I tried echo Thumbnail( .... ) but I don't get any picture in the browser? What did I miss? – Meryan Mar 29 '20 at 22:35
  • imagepng($image); shows nothing. Can I display the image resized from a URL without storing it first? How? Thanks. – Meryan Mar 29 '20 at 23:27
  • Could you kindly explain why I had to wrap your code with ob_start() and ob_end_flush(); ob_end_clean(); stumbled as a comment on another post, because it's been a whole day of grief, trying different thumbnail creator codes include this one, that did NOT want to display this image resource into the browser? I am new to php. – Meryan Mar 30 '20 at 04:10
  • Meryan did you replace it with your own jpg, the one in the example does not exist. – Rob Sedgwick Jun 07 '20 at 13:59
3

You can use this SimpleImage class. You can resize images direct from url and save it in your local like this.

$image = new SimpleImage(); 
$image->load('http://website.com/yourimage.jpg'); 
$image->resize(250,400);
$image->save('filename.jpg');

more example can be found here.

Sachin Joshi
  • 119
  • 5
2

What do these params mean: ($updir, $img, $id) -- Is $updir the location of the file? Or the location where I want it saved? Is $img a file handle or the name of the file? Or the new name of the file? What is $id for? The author didn't give any sample usage.

  • $updir seems to be path to a file on server
  • $img is image filename (with extension)
  • $id seems to be some numeric prefix (purely for creator of this funciton it seems) to the file name. I would change it to $id = '' in the function header.
    .

The function seems to require me to specify WIDTH and HEIGHT. I only want to specify WIDTH and let the height be proportional.

Well, you can use some math. If you want images in 4:3 ratio you can do some "ratio equation" (no idea if it has any name in english):

$thumbnail_width = 1234;
$thumbnail_height = $thumbnail_width * 3 / 4;

But if you don't know ratio and just want to preserve proportions, then I think this function won't help you. You can try SimpleImage class as already said in other answer (it has resizeToWidth() method)
.

I need to pull images over 2 different types of URL: (1) The basic http://foo..., and (2) the data syntax: data:image/jpeg;base64,/9j/4AAQ....

Well, that's up to you. You posted a function here, and what you will pass as parameters is entirely idependent matter. As for base64 encoded images, check this topic to know how convert it to image (you can save image using file_put_content() instead of echoing it).
,

Ideally I'd like to convert these images in all cases down to a compressed jpeg thumbnail (150px width, any height), even if the original image was not in jpg format.

Again, function you posted works entirely on input image and as it is, it cannot convert over different types. Again, I would recommend using SimpleImage class.

Community
  • 1
  • 1
Forien
  • 2,712
  • 2
  • 13
  • 30
0

Here is a good example for converting url to image. It seems a bit working around but it works great ;) For imagemagick , if you use windows, you need to setup imagemagick & show imagemagick dll to php. Click here

Emre Karataşoğlu
  • 1,649
  • 1
  • 16
  • 25
0

I am trying to explaining it in few steps.

1.getImageSize($name)- it needs image name to get image. So,you need to give absolute url along with the exact imagename with extension.

e.g: "abc.com/edit/9/xyz.png"

In above case, as per your function parameter.

  1. abc.com/edit/ is your default url.
  2. $id is your id of your
  3. particular record. '_ ' will append '/' in your url.
  4. $img is image name of particular record.

2, The above function will give you an array, in which first two parameters are Height and Width of the image passed in function. so you need to store it in variables. $height and $width.

3, Next it will check height and width, and if height or width is not according to the requirements,then you need to set it accordingly.

4, Then in the code, next is dest_x and dest_y which will help you to point the position of your image.

And For two different url, you can store those url in constant variable and put this constant variable inside your getImageSize() function.

Piyush
  • 3,947
  • 9
  • 36
  • 69
Viraj
  • 228
  • 5
  • 14