PHP - Read an image with URL - php

Here my problem, I do a query to MySQL (PDO) for give me the last 5 URLs of a table nammed avatar who contains the ID and the URL :
$response = $dbh->query("SELECT url FROM avatar ORDER BY id_URL DESC LIMIT 0,5 ");
And I did :
while ($donnees = $response->fetch())
{
$urlImage = $donnees['url']; //'url' contains the URL
$result = file_get_contents($urlImage);
header('Content-Type: image/png');
echo $result;
?>
But the header just return a small empty white square. However, the "$result = file_get_contents($urlImage);" takes properly the URL because when I do :
$urlImage = $donnees['url']; //'url' contains the URL
$result = file_get_contents($urlImage);
echo $result;
?>
It just shows the "encodage of the image" (a ton of special characters) but not displays the image.
I also try with "imagick" but it says to me that the class doesn't exist and I don't think that the imagecreatefrompng can be use with URL.
Thanks !

Can you try this and see if it works?
$image = file_get_contents($donnees['url']);
$finfo = new finfo(FILEINFO_MIME_TYPE);
header('content-type: ' . $finfo->buffer($image));
echo $image;
This is suppose to handle one Image. One php script can return one image. If you want to combine the images and render a big long image then probably you should look at http://image.intervention.io/
EDIT
What I understood after trying out the above code is that if you put file_get_contents before header then the raw characters are shown. However you put it after header then everything seems to be working
$image="http://www.hillspet.com/HillsPetUS/v1/portal/en/us/cat-care/images/HP_PCC_md_0130_cat53.jpg";
$filename = basename($image);
$file_extension = strtolower(substr(strrchr($filename,"."),1));
switch( $file_extension ) {
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpeg"; break;
default:
}
header('Content-type: ' . $ctype);
$image = file_get_contents($image);
echo $image;
Working fiddle

If you're trying to use a dynamic image source where your url is the image source, and it isn't working, then the problem might be that there's a space or extra character somewhere on the page, which will make the browser treat it like a document instead of an image in some cases.
Your problem is that the browser isn't understanding that it's supposed to be an image.
You could always do:
<img src="<?=$urlImage?>">

Related

Set the header( content-type: image/<ANY IMG FORMAT>)

The php file that handles the images I display only allows one image format, either .jpg, .png, .bmp, etc but not all. The imageName stores the file name of the image stored in the database including its format. this is my code, so far it doesn't work yet and I'm not sure if that's allowed. Can you help me fix it please?
$con = mysqli_connect("localhost","root","","tickets");
$ticket = 109;
$result = mysqli_query($con,"SELECT image, imageName FROM tix WHERE tktNum=$ticket");
while($row = mysqli_fetch_array($result))
{
$image = $row['image'];
$imageName = $row['imageName'];
$format = substr( $imageName, -3 ); //gets the last 3 chars of the file name, ex: "photo1.png" gets the ".png" part
header('content-type: image/' . $format);
}
I just used this, just indicating it's an image but without specifying image type.
header("Content-type: image");
It seems to be working just fine regardless of file type. I tested with IE, Firefox, Safari and the Android browser.
The solution is to read in the file and decide which kind of image it is and basednd on it send out the appropriate header.
$filename = basename($file);
$file_extension = strtolower(substr(strrchr($filename,"."),1));
switch( $file_extension ) {
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpeg"; break;
case "svg": $ctype="image/svg+xml"; break;
default:
}
header('Content-type: ' . $ctype);

PHP - Playing video from dynamic directory path - strange error

I am attempting to include an avi video in a webpage. The video is held outside the webroot folder for security and is dynamically loaded using PHP (see full code below).
A sample full path is '/Users/me/project/1/video/test1.avi';
The page is experiencing a strange error. I build the path to the file using the following statement:
$pic = $CFG->dataroot."/".$COURT->id."/".$preview;
//($CFG->dataroot = '/Users/me/project')
//($COURT->id = 1 - a number representing the folder name.)
//($preview = 'video/test1.avi' - or the location of image/video)
This works for images but fails to load the video showing just the video controls and 'loading...'
EDIT: I have echoed $COURT->id and the variable 1 is being passed correctly
If I change the code and directly specify the directory by removing $COURT->id it works for both video and the images.
$pic = $CFG->dataroot."/1/".$preview; //- works
Any ideas why this might be?
Thanks in advance Steve
(I am testing on a Mac using Apache and Safari.)
Full code:
<?php
$preview = $_GET['preview'];
//works with images but not video
//$pic = $CFG->dataroot."/".$COURT->id."/".$preview;
//works but the folder '1' needs to dynamic i.e. var $COURT->id
$pic = $CFG->dataroot."/1/".$preview;
if ( isset($_GET['preview']) ) {
if (file_exists($pic) && is_readable($pic)) {
// get the filename extension
$ext = substr($pic, -3);
// set the MIME type
switch ($ext) {
case 'jpg':
$mime = 'image/jpeg';
break;
case 'gif':
$mime = 'image/gif';
break;
case 'png':
$mime = 'image/png';
break;
case 'avi':
$mime = 'video/avi'; //$mime = 'video/x-msvideo';
break;
case 'doc':
$mime = 'application/msword';
break;
case 'tif':
$mime = 'image/tiff';
break;
default:
$mime = false;
}
// if a valid MIME type exists, display the image
// by sending appropriate headers and streaming the file
if ($mime) {
header('Content-type: '.$mime);
header('Content-length: '.filesize($pic));
$file = # fopen($pic, 'rb');
if ($file) {
fpassthru($file);
exit;
}
}
}
}
Obviously, when images are sent as $preview (on page before where link to preview is), courtid is sent dynamically to next page, and its OK.
But when video is sent as $preview - courtid its not se(n)t.
Why not, we cannot see in these codes, but codes before, ones that triggers this (play) function.
Try to echo courtid on a page where video should play to check out if it is set as 1 and thats it.
I simply cannot find any other logical solution.

How to read an image with PHP?

i know that
$localfile = $_FILES['media']['tmp_name'];
will get the image given that the POST method was used. I am trying to read an image which is in the same directory as my code. How do i read it and assign it to a variable like the one above?
The code you posted will not read the image data, but rather its filename. If you need to retrieve an image in the same directory, you can retrieve its contents with file_get_contents(), which can be used to directly output it to the browser:
$im = file_get_contents("./image.jpeg");
header("Content-type: image/jpeg");
echo $im;
Otherwise, you can use the GD library to read in the image data for further image processing:
$im = imagecreatefromjpeg("./image.jpeg");
if ($im) {
// do other stuff...
// Output the result
header("Content-type: image/jpeg");
imagejpeg($im);
}
Finally, if you don't know the filename of the image you need (though if it's in the same location as your code, you should), you can use a glob() to find all the jpegs, for example:
$jpegs = glob("./*.jpg");
foreach ($jpegs as $jpg) {
// print the filename
echo $jpg;
}
If you want to read an image and then render it as an image
$image="path-to-your-image"; //this can also be a url
$filename = basename($image);
$file_extension = strtolower(substr(strrchr($filename,"."),1));
switch( $file_extension ) {
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpeg"; break;
default:
}
header('Content-type: ' . $ctype);
$image = file_get_contents($image);
echo $image;
If your path is a url, and it is using https:// protocol then you might want to change the protocol to http
Working fiddle

Image display using php without affecting the html code

I have a question about the images displaying using a function getImage_w($image,$dst_w), which takes the image URL ($image) and the destination width for this image ($size). Then it re-draws the image changing its height according to the destination width.
That's the function (in libs/image.php file):
function getImage_w($image,$w){
/*** get The extension of the image****/
$ext= strrchr($image, ".");
/***check if the extesion is a jpeg***/
if (strtolower($ext)=='.jpg' || strtolower($ext)=='.jpeg'){
/***send the headers****/
header('Content-type: image/jpeg');
/**get the source image***/
$src_im_jpg=imagecreatefromjpeg($image);
/****get the source image size***/
$size=getimagesize($image);
$src_w=$size[0];
$src_h=$size[1];
/****calculate the distination height based on the destination width****/
$dst_w=$w;
$dst_h=round(($dst_w/$src_w)*$src_h);
$dst_im=imagecreatetruecolor($dst_w,$dst_h);
/**** create a jpeg image with the new dimensions***/
imagecopyresampled($dst_im,$src_im_jpg,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);
imagejpeg($dst_im);
}
In a file imagetest.php I have this code portion:
<?php
require 'libs/image.php';
echo '<h1>HELLO WORLD : some html</h1>
<img src="'.displayImg_w('http://www.sanctius.net/wp-content/uploads/2010/05/Avatar-20.jpg',200).'">
';
In the past, I used to write the URL with $_GET paramers defining the image. But now , I want to use the function directly in my code.
The problem is that the image is displaying correctly, but the Hello World HTML code is not translated by the browser (I know that the header are already sent by the first code) But I want to know how to display the image correctly without affecting the html code. and also without using get parameters that change the URL of the image to this undesired form :
libs/image.php?image=http://www.example.com/image&width=200
After my earlier, totally wrong answer, I hope to make up for it with this. Try this code:
<?php
function getImage_w($image,$w){
// Get the extension of the file
$file = explode('.',basename($image));
$ext = array_pop($file);
// These operations are the same regardless of file-type
$size = getimagesize($image);
$src_w = $size[0];
$src_h = $size[1];
$dst_w = $w;
$dst_h = round(($dst_w/$src_w)*$src_h);
$dst_im = imagecreatetruecolor($dst_w,$dst_h);
// These operations are file-type specific
switch (strtolower($ext)) {
case 'jpg': case 'jpeg':
$ctype = 'image/jpeg';;
$src_im = imagecreatefromjpeg($image);
$outfunc = 'imagejpeg';
break;
case 'png':
$ctype = 'image/png';;
$src_im = imagecreatefrompng($image);
$outfunc = 'imagepng';
break;
case 'gif':
$ctype = 'image/gif';;
$src_im = imagecreatefromgif($image);
$outfunc = 'imagegif';
break;
}
// Do the resample
imagecopyresampled($dst_im,$src_im,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);
// Get the image data into a base64_encoded string
ob_start();
$outfunc($dst_im);
$imgdata = base64_encode(ob_get_contents()); // Don't use ob_get_clean() in case we're ever running on some ancient PHP build
ob_end_clean();
// Return the data so it can be used inline in HTML
return "data:$ctype;base64,$imgdata";
}
echo '<h1>HELLO WORLD : some html</h1>
<img src="'.getImage_w('http://www.sanctius.net/wp-content/uploads/2010/05/Avatar-20.jpg',200).'" />
';
?>
This basically is not possible. The webbrowser requests the HTML page and expects HTML. Or it requests an image and expects an image. You cannot mix both in one request, just because only one Content-Type can be valid.
However, you can embed the image in HTML using data URI:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4/8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
Be aware that the base64 encoding is quite ineffective, so make sure you definitly compress your output, if the browser supports it, using for example gzip.
So for you it likely looks like the following:
echo '<img src="data:image/jpeg;base64,' . base64_encode(displayImg_w('http://www.sanctius.net/wp-content/uploads/2010/05/Avatar-20.jpg',200)) . '">';
And make sure displayimg_w() does not output a header anymore.
Furthermore, displayimg_w() needs to be adjusted at the end to return the image data as string rather than direct output:
ob_start();
imagejpeg($dst_im);
return ob_get_flush();

How do I script a php file to display an image like <img src="/img.php?imageID=32" />?

I'm storing banner ads in a mysql table or I should say just the file name e.g: 'imagename.jpg' or 'banner3.gif'.
Obviously I am wanting to track when these banners are loaded so I'm thinking to create a php file called img.php and call it like so
<img src="/img/img.php?imageID=3" />
And that would pull out the image with the id 3 along with updating my hits table etc.
I know how to update my hits table... but what I'm trying to work out is how to code the img.php file so that it simply retrieves the file name and prints it to screen so it works like a regular image.
So far I've got...
<?php
header("Content-Type: image/jpeg");
// insert my db connect file
// update the hits table etc
$sql = 'SELECT * FROM ads WHERE id="' . $_GET['imageID'] . '" ';
$res = mysql_query($sql);
$row = mysql_fetch_array($res);
$image = '/img/' . $row['file'];
imagejpeg($image);
// and this is where I'm at...
?>
I have some problems with the above code which i've extracted from various places to get here. The images could be png/gif/jpg while the header content-type seems to only have space for one type.
Is there a way to have this one file work ok for multiple image types? I'm thinking I should query the table firstly, work out the file extension and then insert the header function based off that.
But what do I actually do when I've got that right and I want the image to then just appear?
thanks to your help here is the final working file
<?php
// make sure we're only getting a number for the query b4 doing stuff
if(is_numeric($_GET['imid'])) {
include('thedbfile.php');
$types['jpg'] = 'image/jpeg';
$types['png'] = 'image/png';
$types['gif'] = 'image/gif';
$sql = 'SELECT file FROM ads WHERE id="' . $_GET['imid'] . '" ';
$res = mysql_query($sql);
$row = mysql_fetch_array($res);
$image = 'img/banners/' . $row['file'];
$extension = end(explode('.', $row['file']));
header('Content-Type: ' . $types[$extension]);
echo file_get_contents($image);
}
?>
You may want to store the image content directly in your Database.
As you said, you need to parse the content type out of the filename. You could also add a field to your database which contains the extension.
$extension = end(explode('.', $row['file']));
Then you have to create an array which contains the header content-type:
$types['jpg'] = 'image/jpeg';
$types['png'] = 'image/png';
then send the header (you will want to check whether the types array contains the extension key and error if it doesn't)
header('Content-Type: ' . $types[$extension]);
Then load your image with
echo file_get_contents($image);
That should do it. Note that you really have to check whether the ImageID parameter is an integer, for safety reasons:
if(!ctype_digit($_GET['ImageID'])) // error
echo file_get_contents($image);
But I doubt your images are actually in /img/ (top level of filesystem hierarchy). And yes, setting up Content-type after you know what type your image is sounds good.
P.S. you extended your code a bit and I have no idea what imagejpeg($image) does ;-)
you can try a header('Location: <URL-TO-IMAGE>'); after you are done with the image.
alternatively, you can detect the extension from file name, and then return the appropriate MIME type.
function mime2ext($mime){
$m = explode('/',$mime);
$mime = $m[count($m)-1];
switch($mime){
case 'jpg': return 'jpg'; break;
case 'jpeg': return 'jpg'; break;
case 'pjpeg': return 'jpg'; break;
case 'png': return 'png'; break;
case 'gif': return 'gif'; break;
}
return '';
}
function ext2mime($fname){
$ext = end(explode('.',$fname));
switch($ext){
case 'jpg': return 'image/jpeg'; break;
case 'jpeg': return 'image/jpeg'; break;
case 'png': return 'image/png'; break;
case 'gif': return 'image/gif'; break;
}
return '';
}
regarding multiple mime type, there's no multiple mime type. Only the latest Content-Type will be sent.
see:
<?php
header('Content-Type: image/jpeg');
header('Content-Type: image/png');
header('Content-Type: image/gif');
?>
The content-type is image/gif.
Something like this will ensure you deliver the image correctly and ensure it is not cached so that a page reload will trigger a new fetch...
//tell client abou tcontent type
header("Content-Type:image/jpeg");
//prevent caching
header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header ("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header ("Pragma: no-cache"); // HTTP/1.0
//how big is it?
header("Content-Length:".filesize($image));
//send image data
readfile($image);
In the end, you just need to turn the image data in the body of your message, along with the right hearder. My code looks like:
header("Content-type: $mime");
echo $this->mBinaryJunk;
You need to set $mime type correctly based on the actual type of the image. You can do this by storing it when you original find the file, or detecting it from the file name.

Categories