Display animated GIF from outside public directory (GD?) - php

Once users upload their images to a non public (i.e outside htdocs or public_html folder) folder, I use GD to fetch the image from that folder. This is all in the name of security, as the images themselves are never displayed without being processed.
The issue lies in animated GIFs, which GD is only capable of displaying by showing only it's first frame.
I know that there are classes out there that can slice the gifs up into their respective frames and "glue" them back together, but I'm looking to display these on the fly...
I don't want to create a new animated gif and show that, but rather have a GD script that renders the image from the information it gets from the photo directory, located outside of the public folder.
Thanks so much!

If you're not manipulating the image at all, I would just return the contents of the file with the correct header.
For example:
<?php
$file = 'whatever.gif';
// Do whatever checks you want on permissions etc
header('Content-type: image/gif');
readfile($file);
?>
Readfile outputs the contents of the file, and the header makes sure the browser sees it as a gif and shows it. Because you're not using GD it will still be animated.
The catch with this method is you'll need to know the content type for each file to server it correctly.
http://php.net/manual/en/function.readfile.php

Related

PHP: How to output image files?

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

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"

Protect image contents from unauthorised people

We all know, this is a very important issue for many web developers. They want to protect direct access or direct readability to their confidential images. The folder that contains all the images is open and anyone can visit that folder, but I want to do something that can protect my image contents, means, if an unauthorised guy looks for an image he may get the image by visiting the appropriate folder but the contents will be invisible or difficult to understand. I think if I get a solution here, many guys will be helped from this question. Writing .htaccess isn't always a stable choice. So, after brainstorming I found some ways how I can protect image contents from direct access. I want to use Imagick with PHP to perform any kind of image editing.
Adding and removing a layer: After uploading, add a layer to make contents of the image invisible. So, if anyone reaches the folder you've stored the images will be meaningless as he will see the layer not the image content. Then remove the layer and show to them who have proper rights.
Converting the image to another format: Convert the image to any format like .txt, .exe, .bin, .avi or any other format so that without editing, the image won't be visible. Convert back to show it to the authorised user.
Image grid: Divide the image into some grids, say, if the image is medium 100 grids and change the position of the grids to make the contents unclear. To do this, we can name each grid like 1, 2, 3 and so on, then change the position to $position - 20. So the grid of position 25 will go to 5, 100 will go to 80, 1 will go to 81 and so on. Reverse the same way to display to the authorised users.
It is never possible to protect completely but we can make it harder. I don't know which of the three is possible with Imagick and which is not. Please tell me if you know. Thanks in advance.
You can put these images in a different folder outside of the public_html (so nobody can access them). Then via script, if a user is logged in, you get the image file content and then change the header. If a user is not logged, you can display a random image or showing a default image.
for example, the public html folder is: /var/www your image folder can be: /registered_user/images/
Then in your PHP script you can write:
<?php
if(!userLogged() || !isset($_GET['image'])) {
header('Location: /');
die();
}
$path = '/registered_user/images/';
$file = clean($_GET['image']); // you can create a clean function that only get valid character for files
$filename = $path . $file;
if(!file_exists($filename)) {
$filename = '/var/www/images/bogus.jpg';
}
$imageInfo = getimagesize($filename);
header ('Content-length: ' . filesize($filename));
header ('Content-type: ' . $imageInfo['mime']);
readfile ($filename);

PHP set an image on my server as uploaded temp file

I am editing a photo gallery script to allow the use of TIFF to be uploaded and saved, but i must keep the files in jpg format also for web viewing.
What I have done is installed image magick to convert TIF to JPEG, once i have it converted I want the script to continue with making thumbnails, zoom images, etc. it makes them from
$_FILES['image']['tmp_name']
Is there a way to set my newly created file as $_FILES['image']['tmp_name']? my new jpeg file path is set to $nw.
basically I need
$nw='path/to/newfile.jpg';
$_FILES['image']['tmp_name']=$nw;
but it does not work. any ideas?
If you need to work on the same file across multiple page requests, move it somewhere safe using move_uploaded_file.
If the functions that you wrote require access to $_FILES['image']['tmp_name'], rewrite them to accept the name of the file as a parameter and call them using the new location of the file as argument.

Image SRC From PHP Script on IIS - Not Displaying Consistently

Last week I converted my page img src values from pointing at image files to using a PHP script to serve up the images. The primary reason was to accommodate both files and database BLOBs as the actual source.
Now when a user goes to a page, sometimes images show and sometimes not. If not, and the page is refreshed\reloaded, then the image appears. When images do not appear, sometimes it is an image the user has already accessed previously today.
I am stumped.
Here is the img tag:
<img src="../somedir/image_script.php?i=1234">
The image_script.php file figures out where to get the image from, then finishes up with:
header("Content-type: image/jpeg");
if($from_db){
print $image_blob;
} else {
$im = imagecreatefromjpeg($image_file);
imagejpeg($im,null,100);
imagedestroy($im)
}
I am using PHP 5.2.8 on IIS 6 using FastCGI. There are no cache headers on the image_script.php file nor on the directory it is in. Currently 99.9% of the images are file based, so I do not know if there is a difference in result between db-based and file-based images. When I go directly to image_script.php in my browser it returns the requested image (i=????) 100% of the time.
a> Any clue as to why the hit and miss with images being displayed? and,
b> what would be a proper way to actually cache the images served up by the PHP script? (they are very static)
Scott
Hmm. Can't tell for sure, but maybe your imagecreatefromjpeg is occasionally running out of memory? In that case, you'd serve an error message out as JPEG data and never see it, right?
Incidentally, wouldn't just grabbing the image file in as a string and shovelling it out without going through imagecreatefromjpeg/imagejpeg/imagedestroy be more efficient? It looks like you're reading a JPEG file, creating an internal PHP memory image from it, then reconverting it to a JPEG (at hefty 100% quality) then serving that data out, when you could simply read the JPEG file data in and print it, like you do from the database.
What happens if you do, say...
...
} else {
header ('Content-length: ' .filesize($image_file));
readfile ($image_file);
}

Categories