Have a PHP page output a static image - php

I want a PHP to be able to send 1 of 3 images, depending on a $_GET[] parameter. I have the images as three separate PNGs right now, and would like the PHP script to have those embedded in it, then return the specified image. So, I want one PHP script instead of 3 images. Is this possible? I don't need to create special images on the fly, just print out one of those. Thanks!

If your images are in files, use PHP's readfile() function, and send a content-type header before outputting it:
<?php
$imagePaths = array(
'1' => 'file1.png',
'2' => 'file2.png',
'3' => 'file3.png',
);
$type = $_GET['img'];
if ( isset($imagePaths[$type]) ) {
$imagePath = $imagePaths[$type];
header('Content-Type: image/png');
readfile($imagePath);
} else {
header('HTTP/1.1 404 File Not Found');
echo 'File not found.';
}
?>
EDIT:
You could also embed your images in the script by encoding them e.g. as Base64, then embed them as strings in PHP, then decode it there with base64_decode to deliver them:
<?php
$imageData = array(
'1' => '...', // Base64-encoded data as string
...
);
$type = $_GET['img'];
if ( isset($imageData[$type]) ) {
header('Content-Type: image/png');
echo base64_decode($imageData[$type]);
} else {
header('HTTP/1.1 404 File Not Found');
echo 'File not found.';
}
?>
You could also use PHP to encode the image on the command line. Just execute this PHP script in the command line (php script.php image1.png image2.png image3.png > output.php) and save its output, and incorporate it into your script:
<?php
$imageData = array();
foreach ($argv as $index => $imagePath)
$imageData[(string)($index + 1)] = base64_encode(file_get_contents($imagePath));
echo '$imageData = '.var_export($imageData, true).';';
?>

I have not tested the following, but it should work. Use this script to get PHP code that will contain the image data.
To get the image:
$image = base64_encode(file_get_contents("image.png"));
// The string $image now contains your image data.
Get this (potentially big) string in your code where you want the image, for each image. Print it and copy it then paste it. Import it as a text file over the web. That's up to you.
Then, to print the image (only the image as if the PHP script were the image), do:
header("content-type: image/png");
print base64_decode($image);
Of course, you would put each image data in an array or something like that.
Let me know if it works.

Yes, it's possible.
Do this:
Write a php script deciding which image to output.
Set the appropriate headers with header() function (I.e. Content-type)
Open the file, read it and send it to the output stream.
Remember that you will probably lose any benefits from browser's cache with this approach...

A fast but not really secure nor elegant way to do it...
<?php
switch($_GET['type']){
case "1":
$image = "image1.png";
break;
case "2":
$image = "image2.png";
break;
case "3":
$image = "image3.png";
break;
}
header('Content-Type: image/png');
readfile($image);
?>
the moral of the story: use header() and readfile() =D

Related

Displaying an image resource with PHP

I am trying to simply get a test image, crop it a bit, and display it. The thing is, I am doing this from PHP, and every attempt I have made thus far has frustrated me even more; /* and the internet is telling me to do things that I have already done. */
OK, so what have you done??
I have tried various ways of getting the $image itself. I have tried the following:
Using imagecreatefromstring($url); /* where $url is the location of the image (I am pulling from random sites, which is a necessity for my project */
Using imagecreatefromstring(file_get_contents($url)); and then, in a <div> tag, echoing the image
Using imagecreatefromstring(file_get_contents($url)); and then, in an <img> tag, echoing the image
Doing 3., except using imagejpeg($image)
Doing 4., except, this time, putting header('Content-Type: image/jpeg');
OK, what happened?
First attempt returned a nice error saying that $image was not recognized.
Second attempt seems to work, but instead of an image, I get back the following text: Resource id #5
Third attempt gives me a bunch of gibberish.
Fourth attempt also gave me a bunch of gibberish.
Fifth attempt gave me a black screen with this error message: The image “http://localhost/ResearchProject/sampleImageDisplay.php” cannot be displayed because it contains errors.
Here is the final code (and header.php just contains all of the necessary HTML tags to display the web page (the DOCTYPE tag, the html tag, the meta tag...) ):
<?php
include "header.php";
$url = "http://byebyedoctor.com/wp-content/uploads/2010/12/alopecia-areata-3.jpg";
$image = imagecreatefromstring(file_get_contents($url));
?>
<img>
<?php header('Content-Type: image/jpeg'); imagejpeg($image); ?>
</img>
<?php imagedestroy($image); ?>
</body>
</html>
Why can't I display this simple image??
This code worked for me. Just create empty php file and paste this code. It should return the photo of a semi-bold man.
$url = "http://byebyedoctor.com/wp-content/uploads/2010/12/alopecia-areata-3.jpg";
$im = imagecreatefromstring(file_get_contents($url));
if ($im !== false) {
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
}
else {
echo 'An error occurred.';
}
First off...
You have to make sure that "allow_url_fopen" is enabled in php.ini.
If you have access to this file just change
;allow_url_fopen
To
allow_url_fopen
Some hosts disable access to php.ini though.
Then all you have to do is this....
$url = "http://byebyedoctor.com/wp-content/uploads/2010/12/alopecia-areata-3.jpg";
$image = file_get_contents($url);
Then you can store it temporarily to resize it or whatever...
//Store in the filesystem.
$fp = fopen("/location/to/save/tempimage.jpg", "w");
fwrite($fp, $image);
fclose($fp);
Your major planning problem is: You try to include you image into a html code.
For this you need 2 phps:
A php file what contains your html-code with an img-tag (src must be the second php-file)
A php file what reads you base image and outputs the BINARY image data
your_htmlpage.php
<html>
<?php
include "header.php";
?>
<body>
<img src="your_image.php">
</body>
</html>
your_image.php
<?php
$url = "http://byebyedoctor.com/wp-content/uploads/2010/12/alopecia-areata-3.jpg";
$image = imagecreatefromstring(file_get_contents($url));
if($image !== false) {
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
} else {
header("X-Error", true, 404);
echo "Error loading remote image";
}
?>
Another option would be to send the image as base64encoded String to the browser. But this means that the WHOLE image-data is part of the html-code.
e.g. lik this:
<html>
<?php
include "header.php";
$url = "http://byebyedoctor.com/wp-content/uploads/2010/12/alopecia-areata-3.jpg";
$image = imagecreatefromstring(file_get_contents($url));
if($image !== false) {
// start buffering and catch image output
ob_start();
imagejpg($image);
$contents = ob_get_contents();
ob_end_clean();
imagedestroy($image);
$img_data = "data:image/jpg;base64,".base64_encode($contents);
} else {
$img_data = "";
}
?>
<body>
<img src="<?php echo $img_data; ?>">
</body>
</html>

Rotate an image on same page

I want to rotate an uploaded and retrieved image from one location. Yes i am almost done. But the problem is, due to header("content-type: image/jpeg") the page redirected to another/or image format. I want to display it in same page as original image in. Here my code..
$imgnames="upload/".$_SESSION["img"];
header("content-type: image/jpeg");
$source=imagecreatefromjpeg($imgnames);
$rotate=imagerotate($source,$degree,0);
imagejpeg($rotate);
i also did with css property.
echo "<img src='$imgnames' style='image-orientation:".$degree."deg;' />";
But anyway my task is to done only with php. Please guide me, or give any reference you have
thanks advance.
<?php
// Okay, so in your upload page
$imgName = "upload/".$_SESSION["img"];
$source=imagecreatefromjpeg($imgName);
$rotate=imagerotate($source, $degree,0);
// you generate a PHP uniqid,
$uniqid = uniqid();
// and use it to store the image
$rotImage = "upload/".$uniqid.".jpg";
// using imagejpeg to save to a file;
imagejpeg($rotate, $rotImage, $quality = 75);
// then just output a html containing ` <img src="UniqueId.000.jpg" />`
// and another img tag with the other file.
print <<<IMAGES
<img src="$imgName" />
<img src="$rotName" />
IMAGES;
// The browser will do the rest.
?>
UPDATE
Actually, while uniqid() usually works, we want to use uniqid() to create a file. That's a specialized usage for which there exists a better function, tempnam().
Yet, tempnam() does not allow a custom extension to be specified, and many browsers would balk at downloading a JPEG file called "foo" instead of "foo.jpg".
To be more sure that there will not be two identical unique names we can use
$uniqid = uniqid('', true);
adding the "true" parameter to have a longer name with more entropy.
Otherwise we need a more flexible function that will check if a unique name already exists and, if so, generate another: instead of
$uniqid = uniqid();
$rotImage = "upload/".$uniqid.".jpg";
we use
$rotImage = uniqueFile("upload/*.jpg");
where uniqueFile() is
function uniqueFile($template, $more = false) {
for ($retries = 0; $retries < 3; $retries++) {
$testfile = preg_replace_callback(
'#\\*#', // replace asterisks
function() use($more) {
return uniqid('', $more); // with unique strings
},
$template // throughout the template
);
if (file_exists($testfile)) {
continue;
}
// We don't want to return a filename if it has few chances of being usable
if (!is_writeable($dir = dirname($testfile))) {
trigger_error("Cannot create unique files in {$dir}", E_USER_ERROR);
}
return $testfile;
}
// If it doesn't work after three retries, something is seriously broken.
trigger_error("Cannot create unique file {$template}", E_USER_ERROR);
}
You need to generate the image separately - something like <img src="path/to/image.php?id=123">. Trying to use it as a variable like that isn't going to work.

How to handle php generated images (without extension)?

Is it possible to work with following kind of image urls?
http://product-images.barneys.com/is/image/Barneys/503230930_product_1
Currently I'm using following code to determine remote image formats. But I don't know how to handle the above mentioned example. Thats one example. Normally they do it for dynamic image resizing.
if($source['extension'] == 'png') {
$type = 'image/png';
}
<?php
$f = tempnam("./", "TMP0");
file_put_contents($f,file_get_contents("http://product-images.barneys.com/is/image/Barneys/503230930_product_1"));
if(getimagesize($f)){
$type = 'image/png';
}
$f file has now the image do whatever you want or delete it using unlink($f);
You could make use of finfo::file extension. You don't need to use cURL for this context.
<?php
$remoteImgTempName = 'someimg';
file_put_contents($remoteImgTempName,file_get_contents('http://product-images.barneys.com/is/image/Barneys/503230930_product_1'));
echo finfo_file(finfo_open(FILEINFO_MIME_TYPE), $remoteImgTempName);
OUTPUT :
image/jpeg

How to make images load faster?

How can I make these images load faster? I have a loop that displays a profiles pictures and the photos take 1 to 2.5 seconds to load. Not one after another but pretty much all at once. I tried re-sizing with PHP but that didn't really change anything. I am not sure how I can pre-load these images with such a loop. What can I do to increase load performance?
PHP
$query = "SELECT `photoid` FROM `site`.`photos` WHERE `profileid`='$profileid'";
try{
$getphotos = $connect->prepare($query);
$getphotos->execute();
while ($array = $getphotos->fetch(PDO::FETCH_ASSOC)){
echo '<div id="photo"><img src="photoprocess.php?photo='.$array['photoid'].'"></div>';
}
} catch (PDOException $e) {
echo $e->getMessage();
}
CSS
#photo img {
max-width:100%;
max-height:100%;
}
photoprocess.php
$photoid = $_GET['photo'];
$query = "SELECT `ext` FROM `site`.`photos` WHERE `photoid`='$photoid'";
try{
$getphotos = $connect->prepare($query);
$getphotos->execute();
$array = $getphotos->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo $e->getMessage();
}
$ext = $array['ext'];
$image = imagecreatefromjpeg('userphotos/'.$photoid.''.$ext.'');
$imagearray = imagejpeg($image, null);
header('Content-type: image/jpeg');
echo $imagearray;
I also have extension checks as "if statements" but those can't be slowing it down this much.
This part
$image = imagecreatefromjpeg('userphotos/'.$photoid.''.$ext.'');
$imagearray = imagejpeg($image, null);
shouldn't be necessary* and is going to be heavy on the server. You're loading (decoding) and saving (re-encoding) the image for no apparent reason.
Use something like fpasshtru():
$name = 'userphotos/'.$photoid.''.$ext.'';
$fp = fopen($name, 'rb');
header('Content-type: image/jpeg');
fpassthru($fp);
Or just link directly to the image. Unless you do some security checks or something, or the images are stored outside the web root, there is no need to go through PHP at all here.
* = unless you have a very specific use case like removing EXIF data from the stored images. In which case you should use some form of caching.
Currently, you are loading image data from disk into an image buffer, which is validated by PHP. After that, you re-encode the image data to a jpg image buffer again and output it.
This is useless. You can just load an thruput the file (read about fpassthru). This is also much more memory efficient, since the image doesn't need to be entrely loaded in memory entirely at once.
That will be way, way faster, but it can be faster still, because I think you can use just .htaccess to redirect an url with an image id to the actual image. You don't even need PHP for that.

Exempting pdf, doc, and xls from screen grab utility

I'm using the following code and an open service provided by wordpress to grab a screenshot thumbnail of a number of webpages on the fly
<img alt="<?php the_title(); ?>" src="http://s.wordpress.com/mshots/v1/<?php echo urlencode( get_post_meta(get_the_ID(), 'mjwlink-url', true )); ?>?w=300">
Problem is some of the links go to PDF, DOC or XLS files, in those cases I'd like to display a single alternative image.
I have absolutely no idea how to go about using the url in this way + given the fact I'm using urlencode I'm not sure it's even possible - any tips/advice/code appreciated.
Example outputs:
http://s.wordpress.com/mshots/v1/http%3A%2F%2Fwww.reform.co.uk%2Fportals%2F0%2Fdocuments%2Fitcanbedonesingle.pdf?w=300
http://s.wordpress.com/mshots/v1/http%3A%2F%2Fwww.outoftrouble.org.uk%2F?w=300
The thing to do would be to check the file type, even by simply checking what comes after the dot.
You can check this before your statement like this:
$types = array('.pdf', '.doc', '.xls');
if(0 < count(array_intersect(array_map('strtolower', $filename, $types)))) {
//go get the image
} else {
//do whatever else you want to
}
where $types can include any types that you want to process differently, and $filename is the name of the file, obviously.
Taken from here, but slightly modified in your case.
$types = array('pdf', 'doc', 'xls');
$path_parts = pathinfo($filename);
if(!in_array($path_parts['extension'], $types)) {
//go get the image
} else {
//do whatever else you want to
}

Categories