I want to download about 200 images from an URL. For instance: Fetch www.web.com/images/001.png and download, fetch www.web.com/images/002.png and download and finish in 200.png.
I've read Grab/download images from multiple pages using php preg_match_all & cURL but I don't know how to modify the PHP to do that thing.
I'll be very appreciated if you can help me. Thank you so much
The simplest way that comes to mind, is to create a for loop, which counts from 1 to 200 and for every count, it then does a request for the image and saves it to the disk (I assume you want to save the image to your disk). Working example can be found at the bottom.
Let's start by settings some variables:
$baseUrl = 'http://www.web.com/';
$localDirectory = 'downloaded_images/';
$maxImageNumber = 200;
The first variable $baseUrl defines where the images will be loaded from. The second defines your local directory in which the images will be saved. Please make sure that this directory exists before running the code, because it will not be automatically generated. The last variable, $maxImageNumber stores the largest image number, which we will need for the for loop.
After setting the variables, we can write the for loop. Separated by semicolons ; there are three parts in the brackets. First one being the starting point of the number we will be counting upwards. The second makes sure we don't go over our limit and the last one just states that the number will be counted up, using the ++ shorthand.
for($imageNumber = 1; $imageNumber <= $maxImageNumber; $imageNumber++) {
// code goes here
}
Inside this for loop we can now generate our file name and download/save the image to the disk. The first line uses the function str_pad() to add leading 0s to the image file (just like in your example) and then adds the extension .png to the name. This allows us to reuse the file name for loading as well as for saving. Second line loads the image with the function file_get_contents() by combining the base and the image file name. In the last line we use file_put_contents() to save the $fileData, we loaded just before, to the disk (using the local directory and the image file name).
$imageFileName = str_pad($imageNumber, 3, '0', STR_PAD_LEFT) . '.png';
$fileData = file_get_contents($baseUrl . $imageFileName);
file_put_contents($localDirectory . $imageFileName, $fileData);
The complete code should look like this:
<?php
$baseUrl = 'http://www.web.com/images/';
$localDirectory = 'downloaded_images/';
$maxImageNumber = 10;
for($imageNumber = 1; $imageNumber <= $maxImageNumber; $imageNumber++) {
$imageFileName = str_pad($imageNumber, 3, '0', STR_PAD_LEFT) . '.png';
$fileData = file_get_contents($baseUrl . $imageFileName);
file_put_contents($localDirectory . $imageFileName, $fileData);
}
In the unlikely event that this all should not work, there are a few things you can try
check that the $localDirectory exists and is writable.
if the file_get_contents() should not work, you can use curl instead
make sure the computer this code is executed on can access the remote server
Thank you so much but imagine that pics are in www.web.com/image_0001_big.png and www.web.com/image_002_big.png and so on... (last will be web.com/image_0200_big.png)
This doesn't work (i don't know why)
<?php
$baseUrl = 'http://www.web.com/images';
$localDirectory = 'downloaded_images/';
$maxImageNumber = 200;
$input='image_';
for($imageNumber = 001; $imageNumber <= $maxImageNumber; $imageNumber++) {
$imageFileName = str_pad($input, $imageNumber, 4, '_big', STR_PAD_LEFT) . '.png';
$fileData = file_get_contents($baseUrl . $imageFileName);
file_put_contents($localDirectory . $imageFileName, $fileData);
}
Thanks. You're amazing! Thanks for the help! I'm learning PHP and I'm a beginner yet:(
My error:
Warning: str_pad() expects at most 4 parameters, 5 given in C:\xampp\htdocs\auto.php on line 9
Warning: file_get_contents(http://www.web.com/images/.png): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in C:\xampp\htdocs\auto.php on line 10
I've found a semi-solution:_
<?php
$baseUrl = 'http://web.com/images';
$localDirectory = 'downloaded_images/';
$maxImageNumber = 400;
$input='image0';
$input2='big';
$extension ='.png';
for($imageNumber = 100; $imageNumber <= $maxImageNumber; $imageNumber++) {
$fileData = file_get_contents($baseUrl . $input . $imageNumber . $input2 . $extension);
file_put_contents($localDirectory . $imageNumber, $fileData);
}
?>
The problem is when... 0001 0009 0010 !! I want to tell php "hey, always 4 digits"
Related
i am trying to upload remote file using below code for testing purpose and to my surprise only last images are being uploaded.. i changed the sequence of images and it was always last image which was uploading rest are failing. inbrowser console i can see below error.
Warning: copy(http://example.com/your-heart.jpg
): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
in /home/example/minimum.php on line 205
it is coming from form with text field name is urls
here is my php
$image_links = explode("\n", $_POST['urls']);
$i = 1;
foreach($image_links as $image_link){
$file_info = pathinfo($image_link);
copy($image_link, '/home/xxxxx/00' . $i . '_original.' . $file_info['extension']);
$i++;
}
any help will be great.
i tried so many different things for copy parameters like single quote, double quote and several other things but always same output. only last image upload and it says all other images are not found. i even tried to replace http with www . my sample urls are
http://example.com/color-your-heart.jpg
output of var dump
array(2) {
[0]=>
string(61) "http://example.com/thumb/color-your-heart.jpg
"
[1]=>
string(64) "http://example.com/thumb/mobile-price-real-time-calculator.png"
}
It looks like there's a space after the filename in the error message. Try removing spaces with trim()
copy(trim($image_link), '/home/xxxxx/00' . $i . '_original.' . $file_info['extension']);
I always use like below.
$image_data = file_get_contents($image_url);
$fileext = 'jpg'; // ext
$thenew_name = 'new random name or something';
$file = $upload_dir . '/' . $thenew_name . '.' . $fileext;
file_put_contents($file, $image_data);
Then use $file with additional relative directory path to save the image for you, like replace $upload_dir with your path variable. You can use into your foreach loop also. Also remove all the extra pert from image url. Most of expert said you in comments.
I got a small problem with my PHP webpage. I want to calculate the size of a directory, but I got 2 folders in them, that I don't want to include in the final size. I use following:
function foldersize($directory){
$size = 0;
foreach (glob(rtrim($directory, '/').'/*', GLOB_NOSORT) as $each) {
$size += is_file($each) ? filesize($each) : foldersize($each);
}
return $size;
}
$home_directory = "./files/" . $user_data['unique_id'] . "/";
$dir = foldersize($home_directory);
$dirdel = foldersize($home_directory . "del/");
$dirtmp = foldersize($$home_directory . "tmp/");
$userspace = $dir - $dirdel - $dirtmp;
When I test, which variable the server is able to return I get following result: The server is able to calculate $dir, but it seems to have problems with calculating $dirdel and $dirtmp. So it returns 0. Both folders, however, have files in them. I hope anybody can help me with that. Thank you
i have tried your code and I think is OK - except one small mistake,
$dirtmp = foldersize($$home_directory . "tmp/"); ... there is typo, double dollar, $$home_directory ... other results from function are fine I think
I want download an image from AWS S3 and process it with php. I am using "imagecreatefromjpeg" and "getimagesize" to process my image but it seem that
Storage::disk('s3')->get(imageUrlonS3);
retrieve the image in binary and is giving me errors. This is my code:
function createSlices($imagePath) {
//create transform driver object
$im = imagecreatefromjpeg($imagePath);
$sizeArray = getimagesize($imagePath);
//Set the Image dimensions
$imageWidth = $sizeArray[0];
$imageHeight = $sizeArray[1];
//See how many zoom levels are required for the width and height
$widthLog = ceil(log($imageWidth/256,2));
$heightLog = ceil(log($imageHeight/256,2));
//more code here to slice the image
.
.
.
.
}
// ex: https://s3-us-west-2.amazonaws.com/bucketname/image.jpg
$content = Storage::disk('s3')->get(imageUrlonS3);
createSlices($content);
What am I missing here ?
Thanks
I think you are right in your question what the problem is - the get method returns the source of the image of itself, not the location of the image. When you pass that to createSlices, you're passing the binary data, not its file path. Inside of createSlices you call imagecreatefromjpeg, which expects a file path, not the image itself.
If this indeed the case, you should be able to use createimagefromstring instead of createimagefromjpeg and getimagesizefromstring instead of getimagesize. The functions createimagefromstring and getimagesizefromstring each expects the binary string of the image, which I believe is what you have.
Here's the relevant documentation:
createimagefromstring - http://php.net/manual/en/function.imagecreatefromstring.php
getimagesizefromstring - http://php.net/manual/en/function.getimagesizefromstring.php
Resulting code might look something like this:
function createSlices($imageData) {
$im = imagecreatefromstring($imageData);
$sizeArray = getimagesizefromstring($imageData);
//Everything else can probably be the same
.
.
.
.
}
$contents = Storage::disk('s3')->get($imageUrlOnS3);
createSlices($contents);
Please note I haven't tested this, but I believe from what I can see in your question and what I read in the documentation that this might just do it.
I am trying to copy multiple images from a remote host (using a URL) to my local box (using XAMPP on my local box to execute the script).
I am using copy(). When I go to execute the copy(), only the LAST image in the array is created. So, if I have 5 image links, only the 5th image gets created and nothing prior even gets a file created.
I have tried CURL and FOpen and then both create all of the files, but all of the files are blank except, again, the last file which is perfectly fine.
$txt_file = file_get_contents('urls_for_images.txt');
if(!empty($txt_file)){
$image_links = explode("\n", $txt_file);
$i = 1;
foreach($image_links as $image_link){
$file_info = pathinfo($image_link);
copy($image_link, 'images/00' . $i . '_original.' . $file_info['extension']);
$i++;
}
}
I am not sure where the problem is occurring, but it seems odd to me that it will copy the last image in the text file, but not any of the others.
Thanks for the help in advance!
The i variable never changes, therefore the code tries to copy a file with the same name over and over again and only the last file is saved.
Try modifying your code this way:
$txt_file = file_get_contents('urls_for_images.txt');
if(!empty($txt_file)){
$image_links = explode("\n", $txt_file);
$i = 1;
foreach($image_links as $image_link){
$file_info = pathinfo($image_link);
copy($image_link, 'images/00' . $i . '_original.' . $file_info['extension']);
$i++;
}
}
You'd be better off with just file(), which reads the file into an array automatically:
$files = file('urls_for_images.txt', FILE_IGNORE_NEW_LINES);
foreach($files as $remote_file) {
$local_file = ....;
copy($remote_file, $local_file);
}
It appears the problem is the text file which line endings are \r\n and you are exploding with only \n. The quickest way to fix this is either explode by \r\n; or trim with default parameters to remove \r from the end of each line.
foreach($image_links as $image_link){
$image_link = trim($image_link);
$file_info = pathinfo($image_link);
...
}
However, the cleanest way to do this is to use file function, which handles line endings automatically. I recommend you to use this approach.
I am currently in the process of writing a mobile app with the help of phonegap. One of the few features that I would like this app to have is the ability to capture an image and upload it to a remote server...
I currently have the image capturing and uploading/emailing portion working fine with a compiled apk... but in my php, I am currently naming the images "image[insert random number from 10 to 20]... The problem here is that the numbers can be repeated and the images can be overwritten... I have read and thought about just using rand() and selecting a random number from 0 to getrandmax(), but i feel that I might have the same chance of a file overwriting... I need the image to be uploaded to the server with a unique name every-time, no matter what... so the php script would check to see what the server already has and write/upload the image with a unique name...
any ideas other than "rand()"?
I was also thinking about maybe naming each image... img + date + time + random 5 characters, which would include letters and numbers... so if an image were taken using the app at 4:37 am on March 20, 2013, the image would be named something like "img_03-20-13_4-37am_e4r29.jpg" when uploaded to the server... I think that might work... (unless theres a better way) but i am fairly new to php and wouldn't understand how to write something like that...
my php is as follows...
print_r($_FILES);
$new_image_name = "image".rand(10, 20).".jpg";
move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);
Any help is appreciated...
Thanks in advance!
Also, Please let me know if there is any further info I may be leaving out...
You may want to consider the PHP's uniqid() function.
This way the code you suggested would look like the following:
$new_image_name = 'image_' . date('Y-m-d-H-i-s') . '_' . uniqid() . '.jpg';
// do some checks to make sure the file you have is an image and if you can trust it
move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);
Also keep in mind that your server's random functions are not really random. Try random.org if you need something indeed random. Random random random.
UPD: In order to use random.org from within your code, you'll have to do some API requests to their servers. The documentation on that is available here: www.random.org/clients/http/.
The example of the call would be: random.org/integers/?num=1&min=1&max=1000000000&col=1&base=10&format=plain&rnd=new. Note that you can change the min, max and the other parameters, as described in the documentation.
In PHP you can do a GET request to a remote server using the file_get_contents() function, the cURL library, or even sockets. If you're using a shared hosting, the outgoing connections should be available and enabled for your account.
$random_int = file_get_contents('http://www.random.org/integers/?num=1&min=1&max=1000000000&col=1&base=10&format=plain&rnd=new');
var_dump($random_int);
You should use tempnam() to generate a unique file name:
// $baseDirectory Defines where the uploaded file will go to
// $prefix The first part of your file name, e.g. "image"
$destinationFileName = tempnam($baseDirectory, $prefix);
The extension of your new file should be done after moving the uploaded file, i.e.:
// Assuming $_FILES['file']['error'] == 0 (no errors)
if (move_uploaded_file($_FILES['file']['tmp_name'], $destinationFileName)) {
// use extension from uploaded file
$fileExtension = '.' . pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
// or fix the extension yourself
// $fileExtension = ".jpg";
rename($destinationFileName, $destinationFileName . $fileExtension);
} else {
// tempnam() created a new file, but moving the uploaded file failed
unlink($destinationFileName); // remove temporary file
}
Have you considered using md5_file ?
That way all of your files will have unique name and you would not have to worry about duplicate names. But please note that this will return same string if the contents are the same.
Also here is another method:
do {
$filename = DIR_UPLOAD_PATH . '/' . make_string(10) . '-' . make_string(10) . '-' . make_string(10) . '-' . make_string(10);
} while(is_file($filename));
return $filename;
/**
* Make random string
*
* #param integer $length
* #param string $allowed_chars
* #return string
*/
function make_string($length = 10, $allowed_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890') {
$allowed_chars_len = strlen($allowed_chars);
if($allowed_chars_len == 1) {
return str_pad('', $length, $allowed_chars);
} else {
$result = '';
while(strlen($result) < $length) {
$result .= substr($allowed_chars, rand(0, $allowed_chars_len), 1);
} // while
return $result;
} // if
} // make_string
Function will create a unique name before uploading image.
// Upload file with unique name
if ( ! function_exists('getUniqueFilename'))
{
function getUniqueFilename($file)
{
if(is_array($file) and $file['name'] != '')
{
// getting file extension
$fnarr = explode(".", $file['name']);
$file_extension = strtolower($fnarr[count($fnarr)-1]);
// getting unique file name
$file_name = substr(md5($file['name'].time()), 5, 15).".".$file_extension;
return $file_name;
} // ends for is_array check
else
{
return '';
} // else ends
} // ends
}