PHP Image content type problem - php

I have a specific problem, and cant get over it.
For my latest project I need a simple PHP script that display an image according to its ID sent through URL. Here's the code:
header("Content-type: image/jpeg");
$img = $_GET["img"];
echo file_get_contents("http://www.somesite.hr/images/$img");
The problem is that the image doesn't show although the browser recognizes it (i can see it in the page title), instead I get the image URL printed out.
It doesn't work neither on a server with remote access allowed nor with one without.
Also, nothing is printed or echoed before the header.
I wonder if it is a content type error, or something else.
Thanks in advance.

Possibly the image doesn't fit into memory. Or your PHP installation doesn't have permissions to make external HTTP calls. Anyway, I suggest you never use echo file_get_contents(), use readfile instead.
Also you should never use raw strings from $_GET or $_POST for file operations. Always strip null-bytes, slashes and double dots from user-provided filenames, or better yet, allow only alphanumeric characters.

I was doing something like this recently, but found this a slow method (I was doing 15+ on a page). This is slow because first your server has to download the image, and then send it to the client. This means for every image it is downloaded twice.
I came up with an alternative - redirection. This allowed the client machines to directly access the other site while hiding the real url in the HTML source code.
$r - is processed above the script, and validated to make sure it is ok.
$webFile = 'http://www.somesite.com/'.$r['type'].'/'.$r['productid'].'.jpg';
header('Location: '.$webFile);
exit();
Granted if someone put my image url in the address bar, it would redirect and the user would see the real url, but it made my page faster and I wasn't too worried about that.

You'll want to ensure that your script is not outputting any white-space. Check before and after the opening/closing PHP tags.
If that checks out, you'll want to ensure that allow_url_fopen is set to On in php.ini

try embedding your php file that retrieves the image as <img> in your html
getImage.php
header("Content-type: image/jpeg");
$img = $_GET["img"];
echo file_get_contents("http://www.somesite.hr/images/$img");
in your html file
<img src="getImage.php?img=IMAGEID">

Probably you get some errors and the image is not displayed. Try to turn off the errors like this first:
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'Off');

Check that the variable exists in the query string, and use a regular expression to make sure that it doesn't contain anything other than alphanumeric characters or a period. Then use readfile() to stream the output to the browser.
// make sure the variable exists
if (isset($_GET['image'])) {
$image = $_GET['image'];
// make sure it contains only letters, numbers, the underscore, and a period
if (preg_match('/^[\w.]+$/', $image)) {
$file = "http://www.example.com/images/$image";
// send the correct header
header('Content-type: image/jpeg');
// stream the output
readfile($file);
}
}

Related

Read multiple image files using php readfile

I am trying to read multiple image files from a folder (.htaccess protected) and display in a HTML page using php readfile().
The problem is I can see only the first image is read and the next is not shown in the browser. The code is as below
<?php
$image1 = 'files/com_download\256\50\www\res\icon\android\icon-36-ldpi.png';
$image2 = 'files/com_download\256\50\www\res\icon\android\icon-48-mdpi.png';
$imginfo = getimagesize($image1);
header("Content-type: ".$imginfo['mime']);
readfile($image1);
$imginfo = getimagesize($image2);
header("Content-type: ".$imginfo['mime']);
readfile($image2);
?>
I could see the first image 'icon-36-ldpi.png' successfully read and displayed in the browser and the second image is not read and not displayed in the browser.
Am I missing something? Any advice please.
Sorry if I am doing stupid but the requirement is to read multiple image files and render in the browser like a grid view. I cannot use img tag because of security reasons.
You can't dump both images out at once. Why not make two images in your html so the browser makes two calls to your script. Then use a GET param to pass the filename you want to display.
---Edit---
Important Security Note
There is an attack vector which you open up when doing soething like this. Someone could easily view your source html and change the parameter to get your image script to output any file they want. They could even use "../../" to go up directories and search for well known files that exist. e.g. "../../../wp_config.php". Now the attacker has your wordpress database credentials. The correct way to prevent against this is to always validate the input parameter properly. For example, only output if the file name ends with ".jpg"

Using PHP to send a certain image

I want to have a PNG picture, but when accessing it, it runs a PHP script, the PHP script should decide what picture to send (using some if statements and whatever). Then the PHP script should read the image file from somewhere on my web server and output it.
Here is the issue, if I get a .png file, and put PHP code in it, it won't work, however, if I use the .php extension, it works, and I can even embed the image into other websites, and the PHP can decide what image to send, but if I want to view that image directly (copy it's URL into my address bar) it doesn't work, it gives me the images plain contents (random jibberish).
Anyone know what to do?
Also This is my first question on Stack Overflow - please tell me if I am doing something wrong.
You need to send Content-Type headers.
For png:
header('Content-Type: image/png');
For others change png to jpg or gif or bmp or whatever.
Please note that header() function must be used before anything is written to output.
First, make sure you have your image image.png somewhere accessible to php.
Then create a php script image.php:
<?php
header('Content-Type: image/png');
readfile('image.png');
The script now acts like it was a PNG image.
It sounds like you know how to send the image, your issue is that you want the URL to look like it's a PNG image.
There are a couple of things you can do. First, if your web server supports URL rewriting (like Apache's mod_rewrite module), you can use a rewrite rule so that the user access the script as something like http://example.com/generated_image.png but your server will translate/rewrite this URL to point directly to your PHP script, so something like /var/www/image_generator.php.
Another option would be to actually name your script "generated_image.png" but force your webserver to treat it like a PHP script. For instance, in Apache you could try something like:
<Location /generated_image.png>
ForceType application/x-httpd-php
</Location>
As a final note, if you're not actually worried about the URL, but worried about the file name that is used if the user decides to save it to disk, you can simply use the Content-Disposition HTTP header in your response. In PHP it would look something like this:
<?php
header("Content-Disposition: inline; filename="generated_image.png");
?>
With that, it doesn't matter what the URL is, if the user saves the image through their web browser, the web browser should offer "generated_image.png" as the default filename.
Simplest version I know...
<?php
header('Content-Type: image/png');
if(whatever)
{
$image=your_image_select_function();
}
// as suggested by sh1ftst0rm with correction of unmatched quotes.
header('Content-Disposition: inline; filename="'.$your_name_variable.'"');
readfile($image);
?>
Then, you treat it like an image file. That is, if this is "pngmaker.php" then, in your HTML document, you do
<img src="pngmaker.php">
You can even do
<img src="pngmaker.php/?id=123&user=me">

How to dynmically draw picture in php gd

Hi I have searched the web for 2 days but did not accomplish what I am looking for.
I have an apache server which will be accessed by 146 students. the user picks an angle from dropdown lets say 45 degress, then user clicks CALCULATE button. Then user clicks DIAGRAM button to see how the sine graph looks like.
Works like charm when i write the image to a file e.g: imagepng($img,"diagram.png");
Now the problem is that the diagram.png will always get overwritten by the last user. So for example if another user logs in and calculates the Sin 135. Both users will see Sine 135 because filename is hardcoded since there is conflict of filename.
I have searched the web on how to create the image dynamically instead of writing to a file and then reading the file. I have come across the following but not working:
base64_encode and decode
What would I have to do to my code of imagepng(...., ...) mentioned above to make use of base64 so I can actually draw the picture of already processed data. Let assume if I comment out the imagepng(..) code, then what do I replace it with. I hope I don't have to change my code a whole lot.
Please help
thanks
Amit
The filename argument to imagepng is optional. From the manual:
filename
The path to save the file to. If not set or NULL, the raw image stream will be outputted directly.
You would just need to send a png header at the top of the script and you would get the image as output for that script.
It's hard to tell without seeing you code how it is structured
but if once the user submits the form all you do is show the image by itself, then you can do something like this.
// make sure nothing else is out put before this otherwise it will stuff up the header
header('Content-Type: image/png);
imagepng($img);
If you embed the image into an html page as the result, then your best best would be to change the url of the image on the success page to something like this.
<img src="/path/to/file.php?deg=45" />
Then in the file.php
$deg = $_GET['deg'] + 0; // make sure it is a number
$img= function_render_graph($deg);
// make sure nothing else is out put before this otherwise it will stuff up the header
header('Content-Type: image/png);
imagepng($img);
By using a GET request, rather then a POST request then the image will likely be cached by the browser, so it doesn't need to be rendered each time. (Given that you have a drop list of angles, there must be a limited number of graphs that can actually be drawn)
Draw_Resultant_Prism_Graph (parameters)
{
$img = imagecreatetruecolor(800,750);
....
....
...
the following lines captures the data from output buffer and displays on same screen
***some version of IE have some issues mostly the dumb terminals where IE update is ADMIN
***restricted
ob_start();
header("Content-type: image/jpeg");
imagepng($img);
$output = ob_get_contents();
ob_end_clean();
imagedestroy($img);
echo img src="data:image/jpeg;base64,'.base64_encode($output).'"
user tags around img above and semicolon af
}

How is $_GET set in this image-resize code?

I am working with a script for resizing images. I seem to be getting an error:
Error: no image was specified
Probably because of this code in the script(image.php):
if (!isset($_GET['image']))
{
header('HTTP/1.1 400 Bad Request');
echo 'Error: no image was specified';
exit();
}
Here is what I'm doing(profile.php):
$your_image = $row['Image'];
$path_to_image = $row['PortraitPath'];
$width = 100;
$height = 100;
echo "<img src=\'/image.php/{$your_image}?width={$width}&height={$height}&cropratio=1:1&image={$path_to_img}\' alt=\'Alt text goes here.\' />";
Therefore, I am reading $your_image and $path_to_image from a MySQL table, and then putting it in the img source. As mentioned above, obviously, image is not set, that is why I am getting that first error. What I don't get is, how will the image actually even be set with my img src code? Aren't I simply displaying the actual image? Then how will image even be set if a picture is simply being displayed? Thank you.
If you want to source a php file instead an image, you need to tell your php file that the output will be an image.
You can do this using the php header() function, like this:
header('Content-type: image/jpeg');
Here is some reference: php header function
About the address you are point to, isn't a bit weird? You have a slash right after the .php, which suggest that you are trying to access some folder... Did you tested this url to see if a real image are being outputted on the screen?
Hope this can help you =)
The URl for the image contains ?foo=bar&this=that&image=path. These variables will be passed to the image.php script in the $_GET array.
As a word of warning, in your profile.php's code I saw this fragment:
image={$path_to_img}
Depending on how you deal with the value of $_GET['image'] this may result in a RFI vulnerability. The user could forge a GET request to image.php with their own "image" path.
A couple things that I noticed, I'm not sure how much of the code you modified before posting it here...
1a) Don't escape the single quotes if you are using double quotes to encompass it.
OR
1b) Change the escaped single quotes to escaped double quotes.
2) In the URL you are using $path_to_img but the variable you have defined is $path_to_image. Make them consistent.

How to display an Image from a mysql blob

I am trying to display an image from a MySQL blob field. I have tried a few different things and none of them seem to work.
I have tried:
header("Content-type: $type"); img src = $blobData;
header("Content-type: $type"); echo($blobData);
<?php
header("Content-type: $type");
echo $blobData;
?>
This code looks perfectly OK. However, I heard a similar complain from another person and I was able to troubleshoot it by assuring that:
The php script does not output any extra character before or after sending the binary image data.
The php script is saved as a pure ASCII text file, not as a Unicode/UTF-8 encoded file. The Unicode/UTF-8 encoded PHP files might include a signature as the first bytes. These bytes will be invisible in your text editor but server will send these few extra bytes to the browser before the JPEG/GIF/PNG data. The browser will therefore find the wrong signature in the beginning of data. To workaround, create a blank text file in notepad, paste in the php code and save the file in ANSI encoding.
Another option you might consider (assuming you are on Apache):
Create an .htaccess file with a mod_rewrite for all image extensions (png, jpg, gif).
Have it redirect to a php script that looks up the image requested in the DB. If it is there, it echos out the header and BLOG. If it isn't there, it returns a standard 404.
This way you can have:
<img src="adorablepuppy.jpg" />
Which then gets redirected ala:
RewriteEngine on
RewriteRule \.(gif|jpg|png)$ imagelookup.php
This script does a query for the image, which (obviously) assumes that the requested image has a unique key that matches the filename in the URL:
$url = $_SERVER['REQUEST_URI'];
$url_parts = explode("/", $url);
$image_name = array_pop($url_parts);
Now you have just the image filename. Do the query (which I shall leave up to you, along with any validation methods and checks for real files at the address, etc.).
If it comes up with results:
header('Content-type: image/jpeg');
header('Content-Disposition: inline; filename="adorablepuppy.jpg"');
print($image_blog);
otherwise:
header("HTTP/1.0 404 Not Found");
FYI: I have no idea if this would be bad in terms of performance. But it would allow you to do what I think you want, which is output the image as though it were a flat image file on the server using a simple image element. I'm inclined to agree that BLOBs are not the best way to go, but this does avoid any cross-browser issues.
I believe that the issue that you are encountering is an issue with encoding. This resource claims that you can use the print function.
Just get the image from the database. And print it using the correct headers.
$image = mysql_fetch_array(...)
header("Content-type: image/jpeg"); // change it to the right extension
print $image['data'];
For performance reasons... this is not advisable. There are several reasons to put images in databases but the most common are:
a) keeping them indexed (duh!)
You can do this by storing the images flat on the server and just indexing the image filename.
b) keeping the image hidden/protected
Flickr and alike still store the images flat on the server and use a different approach. They generate a URL thats hard to find.
This link points to a protected image on my account. You can still access it once you know the correct URL. Try it!
farm2.static - a farm optimized for delivering static content
1399 - perhaps the server
862145282 - my username
bf83f25865_b - the image
In order to find all my secret images any user can hard hit Flickr with the above address and change the last part. But it would take ages and the user would probably be blocked for hammering the server with thousands of 404s.
That said there is little reason to store images on BLOBs.
Edit:Just a link pointing to someone that explained much better than I did why BLOB is not the way to go when storing images.

Categories