I am developing a web application where users can crop images.Users must be able to email the URL so others can view the cropped image. This means every cropped image must be stored on the server so that the URL will never die. The portion of my HTML that contains the cropped image is:
<div class="contain" id="myDiv">
<img src="" id="croppedImage">
</div>
The cropping function works fine and it is written in JavaScript. I am using PHP to parse through the DOM, extract the image and save it on the server but it is not working. Any help will be greatly appreciated.
<?php
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$divContent = $xpath->query('//img[id="croppedImage"]');
$my_server_img = $divContent;
$img = imagecreatefromjpeg($my_server_img);
$path = 'images_saved/';
imagejpeg($img, $path);
?>
After reviewing your code and checking out the functions you are using I looked at this part: $xpath->query('//img[id="croppedImage"]'); and compared to http://php.net/manual/en/domxpath.query.php you can see that the function returns a DOMNodeList element (even if nothing is found it will return the object with no children.. You are then taking this object and passing it to imagecreatefromjpeg($filename) that accepts a string as $filename, not an object. Also your xpath selector is wrong, you need to prefix id with # like so: $xpath->query('//img[#id="croppedImage"]');
So here is some code that will grab an <img /> element off a page by it's id and then download the URL of the src attribute and save it. You will want to make sure that the src of the image you are downloading is a jpg file otherwise imagecreatefromjpeg() will fail. You could use CURL or another method to download images (so you can get png images as well) but that is out of the scope of this answer.
$dom = new DOMDocument();
$dom->loadHTML('
<html>
<img src="http://images.freepicturesweb.com/img1/18/02/13.jpg" id="croppedImage2"/>
<img src="http://images.freepicturesweb.com/img1/18/02/14.jpg" id="croppedImage3"/>
</html>
');
$xpath = new DOMXPath($dom);
$imageElements = $xpath->query('//img[#id="croppedImage2"]');
// make sure $imageElements isn't empty
if($imageElements->length) {
// grab first item in list (should only be one)
/** #var DOMElement $imageElement */
$imageElement = $imageElements->item(0);
// get the src attribute off the <img>
$src = $imageElement->getAttribute('src');
// download and create image resource based off $src
$img = imagecreatefromjpeg($src);
// save image with random name to current directory
$filename = __DIR__.'/'.base_convert(sha1(uniqid(mt_rand(), true)), 16, 36).'.jpg';
imagejpeg($img, $filename);
echo "File saved to: ".$filename;
}
Should also be noted that you were assigning a variable to a variable. Things can get messy quick by doing this. If you want a variable to be called something else just set the name when you initialize it instead of assigning it to another variable with the name you want (I'm guessing this is just something you left over after trying some code out, but still worth mentioning).
Related
I'm trying to make a site where users can submit photos, and then randomly view others photos one by one on another page. I have a directory called "uploads" where the pictures are submitted. I'm having trouble reading the pictures from the file. I just want to randomly select a picture from the directory uploads and have it displayed on the page. Any suggestions appreciated.
You can use glob to get all files in a directory, and then take a random element from that array. A function like this would do it for you:
function random_pic($dir = 'uploads')
{
$files = glob($dir . '/*.*');
$file = array_rand($files);
return $files[$file];
}
I've turned it a little to get more than one random file from a directory using array.
<?php
function random_pic($dir)
{
$files = glob($dir . '/*.jpg');
$rand_keys = array_rand($files, 3);
return array($files[$rand_keys[0]], $files[$rand_keys[1]], $files[$rand_keys[2]]);
}
// Calling function
list($file_1,$file_2,$file_3)= random_pic("images");
?>
You can also use loop to get values.
This single line of code displays one random image from the target directory.
<img src="/images/image_<?php $random = rand(1,127); echo $random; ?>.png" />
Target directory: /images/
Image prefix: image_
Number of images in directory: 127
https://perishablepress.com/drop-dead-easy-random-images-via-php/
Drawbacks
images must be named sequentially (eg image_1.png, image_2.png, image_3.png, etc).
you need to know how many images are in the directory in advance.
Alternatives
Perhaps there's a simple way to make this work with arbitrary image-names and file-count, so you don't have to rename or count your files.
Untested ideas:
<img src=<?php $dir='/images/'; echo $dir . array_rand(glob($dir . '*.jpg')); ?> />
shuffle()
scanDir() with rand(1,scanDir.length)
Or you can use opendir() instead of glob() because it's faster
I have a directory with images like
/Web/ex1_1.png
/Web/ex1_2.png
/Web/ex2_1.png
and I have written HTML and JavaScript to set up two canvas elements, one for ex1_1.png and one for ex2_1.png, and each canvas element paired with a button so that when the first is clicked the canvas erases and re-draws with ex1_2.png. I want, on the next click, for the program to realize there's no next image in the sequence and cycle back to the start, ex1_1.png. I haven't had success with other approaches to this problem, so I'm now trying to have PHP scan the directory and provide a list of files. However, I don't understand how to make PHP send the JavaScript the information. In my JavaScript file I have included
JavaScript
var req = new XMLHttpRequest();
req.open("get", "../php/request.php", true);
req.send()
console.log(req);
and I have a PHP file named request.php
PHP
<?php
echo json_encode(scandir("../Web/"));
?>
The console prints a pretty empty looking XMLHttpRequest and I'm sure I'm thoroughly misunderstanding some principle of how these things relate to each other, but until yesterday I had no experience with PHP and none of the resources I could find told me how to accomplish this.
You can try this code -
PHP (request.php)
$files = scandir("../Web/");
$pngOrJpg = [];
foreach ($files as $key => $value) {
if (stripos($value,'.jpg') || stripos($value,'.png')) {
$pngOrJpg[] = $value;
}
}
echo json_encode($pngOrJpg);
Note: Only getting .jpg and .png type images array.
Javascript
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(xhttp.responseText);
}
};
xhttp.open("GET", "../php/request.php", true);
xhttp.send();
From above code, you can get the JSON array like -
['ex1_1.png','ex1_2.png','ex2_1.png']
Now, Use and manipulate this JSON array with your code.
My previous snippet was missing an ; after the closing ?> in the javascript block. Sorry for that oversight.
I've decided to test my new solution and everything is solid now. Because this question is compound and only enough information has been given to solve the early issues. Please edit your title to something like "Create a json string from array of image files in a remote directory" or similar. For support on any later issues, please post a new non-compound question.
I have a file called canvaswriter.php:
<?php
/* *** Server structure used during testing:
/test
/folder
canvaswriter.php
request.php
/Web
ex1_1.png
ex1_2.png
ex2_1.png
*** */
$path="../Web/";
include("request.php");
?>
<script type="text/javascript">
var images=<?php echo json_encode($pngs); ?>;
console.log(images);
</script>
I wouldn't personally write an include for what is essentially two lines of code to harvest files from the server, but for your specific case you may want to handle all of the javascript on the include too. I don't know where the rest of the magic is going to take place.
Here is request.php:
<?php
echo "Build array of .png images from directory files:<br>";
//$files=array_diff(scandir($path),array('..','.')); // no filetype filter
chdir($path); // set correct directory for glob()
$pngs=glob("*.png"); // with filename pattern filter
print_r($pngs);
?>
The page will display:
Build array of .png images from directory files:
Array ( [0] => ex1_1.png [1] => ex1_2.png [2] => ex2_1.png )
The source code will display:
Build array of .png images from directory files:<br>
Array (
[0] => ex1_1.png
[1] => ex1_2.png
[2] => ex2_1.png
)
<script type="text/javascript">
var images=["ex1_1.png","ex1_2.png","ex2_1.png"];
console.log(images);
</script>
and the console will display:
["ex1_1.png", "ex1_2.png", "ex2_1.png"]
And finally, I don't understand why you are writing these images to a canvas. Are you converting these .png images to base64 and then writing them to the canvas? Is there a reason you can't use them as-is and cycle them? Seems like unnecessary extra work, but again I don't have all the information. I hope this sufficiently solves your issue and helps you to move forward with your project.
I'm trying to use setInterval() to reload an image from a given path. I have some similar code to reload a log file which is working fine:
var auto_refresh = setInterval(
function auto_refresh_log()
{
$('#log_output').load('refresh_log.php').fadeIn("slow");
}, 1000);
refresh_log.php:
<?php $file = "/var/www/html/mainLOG";
$contents = file($file);
$string = implode( $contents);
echo $string; ?>
Now, I want to do something similar only with 2 changes:
Instead of using a fixed path like in refresh_log.php, I want to pass the path from the JS function to the PHP file. How can I do that?
Instead of returning a string, I want to return an image, which is then used in my html document. How can I do that?
To be exact on what I want to do: I have an index.php on which a user can select a file path. After setting some further parameters, some calculations start in the background. The results are saved as TIFF-files which cannot be read by the browser. So I want to use a PHP script with imagemagick to convert them (which is working fine) and pass them back to the JS. Then, the image should be displayed on my HTML <img id="image_id" ... > and refreshed every couple of seconds just like the log file.
Thanks!
One way would be to change the src attribute of the img element.
The browser will download the resource when you change the the src of the img element. Use the jQuery attr to do this. You should append a timestamp parameter so the browser does not obtain a cached instance from the local browser cache.
function loadImg(src) {
// append a parameter of "_" to the url
$("#myimg").attr("src", src + "?_=" + Date.now());
}
setInterval(loadImg("path/to/img"), 1000);
On your PHP side you would need a script that servers the image up in your converted format from where ever you are storing it. An example of how to do that is here.
I've managed to come up with a solution using $.post instead of $.load. The function is called via:
setInterval(
function auto_refresh_img()
{
var img_path = document.getElementById("image_path").value;
$.post('refresh_img.php',
{path: img_path},
function(data) {
$('#my_div').html(data);}
);
}, 1000);
with refresh_img.php looking like this:
<?php $imagepath = $_REQUEST['path'];
if (file_exists($imagepath)) {
$img = new imagick($imagepath."[0]");
$img->setImageFormat('jpg');
$thumbnails0 = $img->getImageBlob();
echo "<img src='data:image/jpg;base64,".base64_encode($thumbnails0)."' id='reco_background' style='display:none' />";
}
else {
echo "Image does not exist.";
};
?>
The returned <img ... > may then be used for any purpose.
I have a remote web page, on which I use CURL and DOMDocument to retrive the src attribute of an image.
I use the following code, mixing JS in a PHP echo
<?php
$toEcho = "";
$toEcho .= // some stuff here...
$toEcho.="
<script>
//I create the object
var img = new Image();
//I set the source with the PHP variable : I get an error because of unexpected token ":"
img.src = $imgsrc;
</script>"
echo $toEcho;
?>
I checked the source, it is valid, and displays properly in my browser(s).
Where could this come from ?
Set the source like this:
img.src = '$imgsrc';
Based on the code in this link http://webaudiodemos.appspot.com/AudioRecorder/index.html, I am making changes to send the recorded audio file to server by passing a sessionId via URL. The php page is http://xxxxx/abc.php?sessionId=Sam. PHP versions: PHP 5.4 PHP 5.5.22. I am using the 2nd method from this link:How to pass variables and data from PHP to JavaScript?. The abc.php page has reference to a few JS codes as with the index.html from the link above. abc.php page process the URL values correctly with the following code:
<div id="bottom">
<?php
$faid = $_GET["sessionId"];
echo htmlspecialchars($faid); // tested working
?>
</div>
On the recorder.js JavaScript,I have a function that tries to pass the URL values to another PHP while uploading the audio file to server - The fname is not being passed on ... it seems .. can the xhr.send(blob) will still send the fname?
Recorder.setupDownload = function(blob){
var div = document.getElementById("bottom");
var fname = div.textContent;
var xhr = new XMLHttpRequest();
xhr.open('POST', "./uploads.php?" + fname, true);
xhr.onload = function(e) {};
// Listen to the upload progress.
var progressBar = document.querySelector('progress');
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
}
};
xhr.send(blob);
The uploads.php in the server has the following script to receive the value and to create an audio file - but it is not creating the audio file - however, if I fix the file name (eg: "filename123") it writes the audio file - so the issue is in passing the variable name - I am a newbie and I wonder what am I missing?:
<?php
ini_set("display_errors", true);
error_reporting(E_ALL);
if(isset($_GET['fileId']) && !empty($_GET['fileId'])){
$id = $_GET["fileId"];
}
$fp = fopen( $id, 'wb' ); // writes the audio file
fwrite( $fp, $GLOBALS['HTTP_RAW_POST_DATA'] );
fclose( $fp );
?>
Update: It is working!
You didn't give your value a name, so you're passing a value that will appear as DIFFERENT key in every page.
e.g. each of your users will have something like
http://example.com?foo
http://example.com?bar
leading to $_GET['foo'] and $_GET['bar'] in PHP. But since foo/bar are some randomish value representing your session ID, you have no idea what that value will be. So... give it a name:
http://example.com?key=foo
Now you just do $key = $_GET['key'] and can always access your session value, no matter what value it really as - it'll always be assigned to the key.