PHP Link to image outside root folder [a href, not img src] - php

Here's my situation: Images are stored outside root folder. I can access them with an external php file (as it should be) then file_get_contents then echo then img src it then it will show perfectly.
I have thickbox installed and what I want to happen is when a user clicks on the image, it will show in the thickbox enlarged
<a href="img.jpg" class="thickbox"><img src="my_image_processing.php?img=img.jpg" />
I'm trying to create a gallery upon clicking. What happens is the thickbox shows up but the image doesn't. Instead of the image, the gibberish/garbage codes show up with black diamonds with a questionmark. I suppose this is the raw code of the image.
How can I output that as image and not raw code in
<a href> 's
ADDED: I just played around with it a bit more. When I remove the thickbox class, the a href actually works. It displays the image normally on the next page. Unforunately when I attach the thickbox classes, it shows the thickbox, but it shows the raw code

Try:
header ("Content-type: image/jpeg");
If you see the raw image data as text, probably your browser does not recognize the output as an image. You can signal the right mime type with the header line above.
It is also possible that an error occures and error messages make the image file unreadable (because instead of the headers the stream starts with an error message). In that case you should see the error message before the characters.

In your example you are using the jpg file directly, it should be something like:
<a href="my_image_processing.php?img=img.jpg" class="thickbox"><img src="my_image_processing.php?img=img.jpg" />
That is, the php page that read the hidden folder and return the image.

Thickbox recognizes the type of the resource linked by the file extension to determine, whether it is an image to be displayed, or not. It also ignores the query string when determining extension. Thus, you have the following options:
use some custom URL rewriting and make your script work eg. using URL like my_image_processing/img.jpg instead of my_image_processing.php?img=img.jpg (search for more info on "mod_rewrite"),
rewrite the code of ThickBox (or search for option parameters allowing you to change that recognition mechanism without changing the code - I did not find any), or
implement other library allowing you to implement what you need (and allows you to use the external script in a way you intended),
One thing is making Thickbox think it loads image, not a page into the frame, and the second one is - as vbence pointed - adding proper mime type to the image you return with your script: you should add appropriate header with "Content-Type" information.
EDIT:
The code responsible for displaying images begins as follows [sic!]:
var baseURL;
if(url.indexOf("?")!==-1){ //ff there is a query string involved
baseURL = url.substr(0, url.indexOf("?"));
}else{
baseURL = url;
}
var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/;
var urlType = baseURL.toLowerCase().match(urlString);
if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images
You may wish to add another type ('php'), if you choose to modify the script yourself, but you should be aware of the consequences.
EDIT2:
If you go with the 'change plugin' option, there is some alternative (ColorBox), that makes you able to decide without the need to dig into the code, whether the *.php link should be treated as image. Just look for the photo option within the documentation (when set photo=true should behave as you would expect).

You've probably neglected the http headers for displaying an image.
header("Content-type: image/jpeg");
header("Content-Disposition: attachment;");

Related

Show image based on access privilege

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?

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"

Get image source from given URL with javascript or PHP

What I want to do is following:
User takes screenshot with the application like jing. ok!
Pastes link that Jing returned back. ok!
Server processes the link that user entered, and extracts images source url. But, I have no idea how server will get "clean" image source URL. For example, this is the link that Jing returned after sharing screenshot http://screencast.com/t/zxBzNNkcg but real url of image looks like http://content.screencast.com/users/TT13/folders/Jing/media/c25ec5c6-bc6a-413c-a50b-ada95fac4ed2/2012-07-25_0221.png
Server returns back image source URL. no idea!
Is there any possible way to get image url with Javascript or PHP?
you could use Simple PHP DOM Parser to retrieve the image from the url without considering the url for as long as it contains and image inside, like so:
foreach($html->find('div[class=div-that-contain-the image]') as $div) {
foreach($div->find('img') as $img){
echo "<img src='" . $img->src . "'/>";
}
}
That is my solution.
You can retrieve the page containing the image using a DOM library like Query Path.
Using that you can extract the URL to the image.
So in your step 3:
Get source of shared screenshot page (maybe use file_get_contents)
Extract screenshot's image src, using Query Path.
Return image src URL to user
Yes. If you right click on the image and go Copy Image Location, you'll see it's http://content.screencast.com/users/TT13/folders/Jing/media/c25ec5c6-bc6a-413c-a50b-ada95fac4ed2/2012-07-25_0221.png
If you were to do it programmatically, you would use cURL and simplehtmldom.sourceforge.net to parse the outputed HTML for the actual link.
Javascript answer:
Will the output image always have the same class, embeddedObject?
If so, how about something like:
myVar = document.getElementsByClassName('embeddedObject');
myVar[0].getAttribute("src");
The myVar[0] reference of course assumes that there is only ever one image on the page with the embeddedObject class, otherwise you'd need to sort, or know which index to reference each time.
Also, this sadly doesn't seem to be supported in IE8 (which browser do you need to support?):
http://caniuse.com/getelementsbyclassname

matching file extension in the document via javascript

This is continued from my original question (http://stackoverflow.com/questions/10133976/getelementsbytagname-specific-links-only) which I got resolved but now facing different issue.
I'm implementing Anarchy player on my site and problem is that script stores files outside the domain root so links to them are in format like ( http: // mysite.com/mod/file/download.php?file_guid=fileID) which is fine for the player, it still plays the file but I need to separate files by type.
Look at the javascript code below, "if(o.href.match(/.mov$|.mp4$|.m4v$|.m4b$|.3gp$/i)" part, if I understand it correctly it says if file extension is .mov, .mp4, etc. than include that player. But since link is not in standard format with file name and extension it does not recognize it.
How to change that "if(o.href.match" to something that would distinguish what type of file it is?
I can pull file full name with extension in text format via PHP code and maybe wrap it in or div and that use if...div.match(...?
Link to video file is already inside div block id "video"
<div id="video">
</div>
Here is javascript:
var all = document.getElementById ( "video" ).getElementsByTagName ( "a" );
for (var i = 0, o; o = all[i]; i++) {
if(o.href.match(/\.mov$|\.mp4$|\.m4v$|\.m4b$|\.3gp$/i) && o.className!="amplink") {
Thank you so much for any suggestions.
It's not always possible to decide upon the filetype of a file just by looking at the filename. A better approach is to look at the Content-Type header (in case of an HTTP resource) or the MIME-type (which is essentially the same thing).
It's still possible to send a bad Content-Type so perhaps there is a way to identify the filetype by looking at the first few bytes? I know PNG starts with a very obvious indicator.

How do I load an image in PHP

I want code that loads an image to a PHP server and then send it to browser.
For example I want sample.php to send an image to browser once it is requested.
in other words, I want to create a PHP file that acts like a proxy for an image.
why are you doing this?
why don't deliver the image directly?
if you are trying to display a random image you may as well just redirect to the image using
header("Location: address-of-image");
for delivering the file to your clients from your server and not from its original location you can just do. however your php.ini settings need to allow external file opens
readfile("http://www.example.com/image.jpg")
correct headers are not required if you are going to display the image in an img tag,
altough i would recommend it. you should check the filetype of the image or in most cases just set an octet-stream header so the browser doesnt assume an incorrect type like text or something and tries to display binary data.
to do so just do
header("Content-type: application/octet-stream")
one more thing to consider may be setting correct headers for caching...
You need to use
$image = fopen("image.png");
Modify the headers(not sure exacly if it's correct)
headers("Content-type: image/png");
And then send the image
echo fread($image, file_size("image.png"));

Categories