I am struggling with PHP's GD library.
I have written a script called foo.php which outputs a png:
header('Content-type:image/png');
$img = imagecreatefrompng($url) or die('bad url:'.$url);
imagepng($img);
imagedestroy($img);
It works fine. Its purpose is to accept a GET parameter and then spit out the appropriate graph:
(e.g.) foo.php?id=2 puts a nice graph in any browser.
Here's my problem:
In another script (baz.php), I'd like to use readfile or something similar to take the image created by foo.php and have baz.php send it to the browser. But no matter what I try, it won't seem to work when I call baz.php
Example from baz.php:
switch($id) {
case '1':
readfile('foo.php?id=1');
break;
case '2':
readfile('foo.php?id=2');
break;
// and so on...
}
I get an error saying:
failed to open stream: No such file or directory...
If I put in the full url or the path:
readfile('http://localhost/dev/foo.php?id=1');
readfile('C:/xampp/htdocs/dev/foo.php?id=1');
...I get the same error.
If I add the header to baz.php:
header('Content-type:image/png');
readfile($url);
In firefox I get "The image "http://localhost/dev/baz.php" cannot be displayed, because it contains errors. In Chrome it shows a broken image 27.82kb in size with dimensions of 0x0
allow_url_fopen is on, and as I mentioned, foo.php is producing pngs without any problems; I just can't seem to get in out of baz.php, which I need to.
I can, for instance just put:
header("Location: foo.php?id=1");
and it will redirect and output the image, but I don't want to do a 302 redirect, I need baz.php to push the image out to the browser. If I save the file as a static file, it will load that fine as well. It just doesn't seem to want to handle the dynamic file.
Any help is very much appreciated. Thanks in advance.
Figured it out:
Issue #1:
You cannot use php's readfile() to include a png that is generated dynamically by php if it is on the same server.
Why? Because readfile will include the raw php code rather than rendering that php code into an image. If you want to call it from another server, readfile works fine.
So, you can include/require the file instead (so it will be rendered into a png), however...
Issue #2:
You cannot include a file with parameters / query string directly (e.g. the following code will error that it cannot open the file:
include('baz.php?id=1'); //this won't work
Solution:
Set the parameter manually in the GET string (e.g. $_GET['id'] = 1;)
Include the file: include('baz.php');
Also note: Apache's virtual() command will also not work with GET because only QUERY_STRING is passed along ($_GET is copied from the parent script):
PHP.net's description of virtual()
this should work http://theserverpages.com/php/manual/en/function.imagecreatefrompng.php
Related
I am trying to display img_a.png or img_b.png based on the access level of the user (e.g. signed in or not). Of course the content (in this case img_a and img_b) should not be available to the general public.
I tried a few solutions, none of them helps me and that's why I look for help here. What I tried so far is:
Based on the user checks I tried adding the resources folder to "open_basedir" which is a lame option but was looking the easiest solution. All ended up by raising a warning that resource is not in the basedir folder through it's obviously there.
Attempted to put the resources in the public folder and restrict them via .htaccess. But in this case they got restricted not only for the unwanted audience but for everyone.
Final and closest attempt was to put back the images outside the webroot and write a class that validates the access and serves the image like:
class Image {
...
public function getImage() {
...
header('Content-Type: '.$this->type);
readfile($this->item);
which afterwards is displayed in the initial script through:
echo "<img src=".$image->getImage($file).">";
The problem above is that the headers were already sent so I could either stream the image or the html output of the .php page but not both. Do I have a way out there?
Create a script that checks whatever user attribute you want, determines what image to serve, and read/send that image. Use the script URL as the <img src=... attribute, ie
<img src='/scripts/user_image.php'>
Something like this will work for PNG images. Similar functions exist for GIF, JPG, etc.
<?php
// do stuff here to determine file name of image to send
if($_SESSION['userlevel']=="ADMIN"){
$imageFilename="admin_image.png";
}
// Create Image From Existing File
$image = imagecreatefrompng($imageFilename);
//Set the Content Type
header('Content-type: image/png');
// Send Image to Browser
imagepng($image);
// Clear Memory
imagedestroy($image);
exit;
?>
OK, per your comment, I think you are referencing things wrong.
My working script is exact as above, only the if-then is commented out. I'm just assigning the filename to the variable. I've named the script user_image.php.
A simple index.html file to reference the image -
<html>
<head><title>test</title></head>
<body>
Hello World!<br />
<img src="user_image.php">
</body>
</html>
And it Just Works. See it in action at https://itsjustcrap.com/img or grab source at https://itsjustcrap.com/img/src.zip
I'll leave it up for a few days, but other than a png image and a commented out if-then, the source is exact same as what is in this post.
Actually I think I found a solution to the headers confict I had.
Displaying the image as data like:
<img src="data:image/png;base64, <?=base64_encode(file_get_contents($file))?>" alt="img">
instead of feeding it inside the source attribute with readfile() php script like:
<img src="image.php?<?=$file?>" alt="my_image">
where the last one was giving me a headers conflict when inside html page.
Discovered the solution over here How to display Base64 images in HTML?
I would like to add images to a dynamically generated page (I use my own template system) with PHP.
NOTE: I regulate image access for security reason.
The folder that contains the images is above the site root, therefore not accessible by HTML links.
I believe there is a method in which PHP returns a file as a resource, specifying the type in a header, and (correct me if I am wrong) a function specifically designed for that imagejpeg().
Please advise, and if possible write a simple example.
What you need to do to output image files is in order:
PHP loads the image from the file, this is file_get_contents or otherwise fopen to open and access the file itself. If the file is a specific image file you can open the file with imagecreatefromjpeg() which will do just that, generate an image file from a JPEG source.
Then, once the file is loaded from anywhere on your filesystem, including directories outside of your web root, PHP can output the data caught in point 1, above, with some HTTP Headers and direct reference to the loaded image.
NOTE: this means that the sole output of this PHP file is the image,
so file.php === image.jpg in this case.
So a brief example:
image is stored in /home/images/image1.jpg
PHP file runs from /home/site/imagecall.php
PHP file says:
<?php
if (file_exists('/home/images/image1.jpg')){
$image = imagecreatefromjpeg('/home/images/image1.jpg');
if ($image){
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
}
else {
die("Image could not be loaded");
}
}
This is a starting point for you and by no means an absolute guide. Explore.
Useful references:
http://php.net/manual/en/function.imagecreatefromjpeg.php
http://php.net/manual/en/function.file-get-contents.php
Following is the piece of code which is not working:-
img src="/old/datagraphsarchive.php?graphing=1&streamCode=ATQ_CALD&date=2008-07-04&iver=1"
Is there any problem with the way I have specified the image source?
This is potentially loading the php file directly instead of as a script. Try using the full external URL in your img src and see if it works.
For example: http://www.yoursite.com/old/datagraphsarchive.php?graphing=1&streamCode=ATQ_CALD&date=2008-07-04&iver=1
If that works, I've yet to actually determine what causes the phenomenon, but you can use the full external url!
If neither work, then your problem lies in the way you're generating your image from the graphsarchive.php file. Ensure you are setting the correct Content-Type headers and writing the binary stream to the page content, like so:
$file = 'myimage.jpg';
header('Content-type: image/jpeg');
readfile($file);
I need to get a image saved on a mysql DB to a folder into the server...
I have the script: watch_pic.php the which get the byte of the image and prints it into a based64 code, I send the Header and the image can be seen on browser, then if I write on the browser 'watch_pic.php?id=1234' it will display and image. I need to copy these image to a folder in the server with any name... I think that using the 'copy' function I could get the image, but it don't works. I can do it using CURL, but I don't wanna like to use this, cause i haven't install it on the server, and could be conflictive with other extras... How can I caopy the image without using CURL??
If you included the code of watch_pic I could give you the exact code to make it work (and if you put it up I can certainly improve this answer). However I can give you a suggestion:
somewhere in that file there will most likely be a line like this:
imagejpeg($img);
(or imagepng or imagegif)
and just change that to something like this:
if (isset($_GET["save"]) {
imagejpeg($img,$_GET["save"]);
}
else {
imagejpeg($img);
}
and call it by image_pic.php?id=####&save=filepathandnametosaveto.jpg
HTH;
Nick
What are some possible ways to save an image or make use of it that is generated from a PHP script. Using save as it does not help though.
This is not an image created by me that's why I want to avoid get_contents.
here is the picture
and here is the url
https://render01.fontshop.com/fonts/font_rend.php?idt=f&id=38005&rbe=fsifr&rt=how+do+I+save+this?&rs=38&w=500&bg=ffffff&fg=000000&tp=0.0
Just write the content of the URL to a file
<?php
file_put_contents("img.png", file_get_contents("http://render01.fontshop.com/fonts/font_rend.php?idt=f&id=38005&rbe=fsifr&rt=how+do+I+save+this?&rs=38&w=500&bg=ffffff&fg=000000&tp=0.0"));
Using file_put_contents() function. If you don't have data in variable and want to readout use file_get_contents()
Since you are not generating the image in your own code, the simplest would be a combo of file_get_contents and file_put_contents:
$url = '...'; // your url here
$data = file_get_conents($url);
file_put_conents('image.png', $data);
In this specific case the render is a PNG image, but if there's a possibility of it being a JPEG or something else then you need to somehow detect that as well. I 'm not giving any suggestions for this because there's not enough info to go by.
You can define a filename in imgpng() or the other functions to tell PHP to store the picture instead of sending it to the calling browser.
I understand you want to save it on the client, with a browser, not on the server.
"Save as" worked fine for me (Firefox 7). In Chrome you'll have to specify the extension of the filename manually. Did not test other browsers, but it should work similarly
You can do this from the terminal using the curl command.
curl -o out.png 'http://render01.fontshop.com/fonts/font_rend.php?idt=f&id=38005&rbe=fsifr&rt=how+do+I+save+this?&rs=38&w=500&bg=ffffff&fg=000000&tp=0.0'
This will save the file as out.png
use imagepng function.
It will return file to browser or save it specified location.
Need to set parameter for function to save image on specified location.