PHP - images stored as BLOB displayed as broken links - php

I'm working on a store application in PHP and am having trouble displaying stored on MySQL database. I'm storing the images as medium BLOB type and I'm confident that the images are properly formatted during and after being uploaded to the database. (I can download the images from the database directly and view them as jpeg images).
But if I try to display my images in the web page, I am getting the broken image icon. The only way I've been able to get the picture to display from sql is by using base64 encoding, but that's not the method I want to use.
Here is my code. It fetches all the products from the database and displays their id, description, and image in a table row.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Image Test</title>
<body>
<?php
include("mylibrary/login.php");
login();
$query = "SELECT prodid, description FROM products";
$result = mysql_query($query) or die(mysql_error());
echo "<table width=\"50%\" cellpadding=\"1\" border=\"1\">\n";
echo "<tr><td>Product ID</td><td>Description</td><td>Image</td></tr>\n";
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$prodid = $row['prodid'];
$description = $row['description'];
echo "<tr><td>$prodid</td><td>$description</td>\n";
echo "<td><img src=\"showimage.php?id=$prodid\" width=\"80\" height=\"60\"></td></tr>\n";
}
echo "</table>\n";
?>
</body>
</html>
This is the showimage.php code. The showimage.php file is only showing a broken image. I've looked at the raw data of the images and they're all formatted correctly. :
<?php
//header('Content-Type: image/jpeg');
$prodid = $_GET['id'];
$con = mysql_connect("localhost", "test", "test") or die('');
mysql_select_db("store", $con);
$query = "SELECT picture from products WHERE prodid=$prodid";
$result = mysql_query($query);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
$picture = $row['picture'];
header("Content-type: image/jpeg");
echo $picture;
?>
I'd really appreciate help in understanding why this code isn't working. I've read numerous articles on this site and from google searches and they all say that this code should work.
As a side note, I don't want to use the base64 encoding method because I'm taking a class and this is the method that we're using (I'm also the only person who is having this problem).

Generally, the code looks almost okay. The problem with pictures is, it has to be exactly correct, otherwise it cannot be correctly displayed. Try the following things:
Use "Content-Type: image/jpeg instead of "Content-type: image/jpeg"
Remove the closing tags ?> in showimage.php - if there is a space after the closing tags, that could be your problem. You should never use closing tags for PHP-only files.
If that does not help, remove the header for the content type and have a look at what is actually returned to you by calling the picture url and compare the data to the original image. That way you can confirm that the picture data is correct or what the differences are.

Related

PDO to retrieve and display images without creating files

Trying to loop through a test database with images (I know many say not to do this, but it simplifies so much in terms of backups, etc.). I can get the result I want by creating image files on the fly, but there must be a way to do this without creating files. Can someone suggest a syntax I can use without having to create these image files?
Here is what I have working:
<?php
// configuration
$dbhost = "localhost";
$dbname = "test";
$dbuser = "root";
$dbpass = "";
// database connection
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
// query
$sql = "SELECT id,title,author,description,cover FROM books";
$q = $conn->prepare($sql);
$q->execute();
$q->bindColumn(1, $id);
$q->bindColumn(2, $title);
$q->bindColumn(3, $author);
$q->bindcolumn(4, $description);
$q->bindColumn(5, $cover, PDO::PARAM_LOB);
while($q->fetch())
{
file_put_contents($id.".png",$cover);
echo ("<img src='".$id.".png'><br />, $title, $author, $description,<br/>");
}
?>
I am thinking that we should be able to eliminate the "file_put_contents.." line and in the echo line, replace the
<img src='".$id.".png'>"
with some php/pdo statement that retrieves the blob and puts it in the proper format. Tried a few things, but have not been successful.
Any suggestions would be helpful!
you do not need to do it in 2 separate files and invoke the script in src attribute of img tag.
Try do this
echo '<img src="data:image/'.$type.';base64,'.base64_encode($image).'"/>';
Where $type is the extension of the image(.png/.jpeg/....) and $image is the binary of the image that you have stored in your DB. in my case I pull the value of the type of image from the db, if you store always the same extension(ex jpeg) you can simply write:
echo '<img src="data:image/jpeg;base64,'.base64_encode($image).'"/>';
the method is an alternative to do that with 2 files.
You need to write code in 2 files. As when browser gets <img src="path/to img_file"> code (or code like <script src="....">), etc, a separate request is sent to server by browser at src path value. So, you also need to create file img_file.
Pseudo code is below,
Firstfile.php
<?php
..................... Other code
while($q->fetch())
{
?>
<img src="image.php?id=<?php echo $id; ?>"><br />,
<?php
echo "$title, $author, $description<br/>";
}
?>
And at image.php file,
header('Content-Type: image/png');
$id = $_GET['id'];
$query = " ..... where id = '".$_GET['id']."'";
//You need error handling if $_GET['id'] is integer and valid value. I am not writing this error handling code
if($q->row_count!=1){
//no database row found. It's error.
echo "Show no image found image. As browser expects image you can not write text here";
die;
}
//it's valid image, else code is already terminated by above die.
while($q->fetch())
{
//show image
echo $cover;
}
?>
I wrote Pseudo code exact code depend on requirements.
If you want .png extension, you can use Apache rewrite. Google it you will get it.
When first time i wrote answer, I missed last php ending tag. By the way, last ending tag ?> is optional in php.
If you are getting X , it seems first file code is ok. As imag_file is not at server, it's showing 404 error. View source to check whether $_GET['id'] is correct. If id is correct, then you want to write at file img_file.php

Reading an Image file from a mysql database using php

I am trying to display an image, but my webpage displays encoding stuff instead. Below is my code:
<?php ob_start();?>
// html markups goes here
<?php include 'login.php';
if(isset($_GET['productid'])){
$productid = $_GET['productid'];
$sql = "select tyre_image from tyres where product_id = '$productid'";
$result = mysql_query($sql) or die(mysql_error());
header("Content-type :image/jpg");
echo mysql_result($result,0);
}
ob_end_flush();
?>
I am using $_GET associative array($_GET['variable']) to get the product ID via a link on another page.
How would I fix this?
I had no idea the Content-type header was this picky, but change the spacing around the colon (and also image/jpg should be image/jpeg):
header("Content-type: image/jpeg");
Per the answer below, I agree - this fix assumes that this script is just used for displaying an image in your HTML, ala <img src="path/to/your/image.php?productid=123" />.
Further light reading on the image/jpeg MIME type spec here.

Display multiple images with PHP

I have this PHP script that returns pictures from the database. I am using a loop now to return 5 pictures at once, but I think they are all overlapping so I am only seeing one. How can I shift each picture a couple of pixels over so I can see the other pictures?
<?php
$mysqli=mysqli_connect('localhost','root','','draftdb');
if (!$mysqli)
die("Can't connect to MySQL: ".mysqli_connect_error());
$param = isset($_GET['rarity']) ? $_GET['loopcount'] :null;
$stmt = $mysqli->prepare("SELECT display.PICTURE_ID
FROM cards
INNER JOIN display ON cards.DISPLAY_ID = display.DISPLAY_ID
WHERE display.DISPLAY_ID=? AND cards.CARD_TYPE =?" );
$cardtype='Rare';
for ($i=0; $i<=5; $i++)
{
$num[$i] = rand(16,30);
for ($j=0; $j<$i; $j++)
{
while ($num[$j] == $num[$i])
{
$num[$i] = rand(16,30);
}
$displayid= array_shift($num);
}
$stmt->bind_param("si", $displayid, $cardtype);
$stmt->execute();
$stmt->bind_result($image);
$stmt->fetch();
header("Content-Type: image/jpeg");
echo $image;
}
?>
You can't "display" an image with php. You do that with HTML using the <img> tag. What you do is printing the raw image data and then telling the browser It's a picture. I'm not sure what's gonna happen if you do this and print multiple images, but It's up to the browser how It should handle this probably.
This is sometimes done with one image if you for example store them as blobs in a database. But not for this purpose of displaying them.
If you want to merge images you can do this with the GD library in PHP.
You can only send one picture to the browser with Content-Type: image/jpeg. I can think of two ways to send multiple pictures.
1.Use GD to make a new picture containing all of the other pictures and send it.
2.Send an HTML page instead of the picture:
<?php
//some code which gets the images and puts them in an array - $images
?>
<!DOCTYPE HTML>
<html>
<body>
<?php foreach($images as $image):?>
<img src="data:image/jpeg;base64,<?php echo base64_encode($image);?>"/><br/>
<?php endforeach;?>
</body>
</html>
edit: It seems browsers have difficulty parsing very large HTML documents fast, so if you have large or lots of images it might be better to load them in separate HTTP requests (src="image.php?image=xxxx").

PHP: Image retrieval from MySQL Blob directly into <img> tag

I've stored my Images into (Medium) BLOB fields and want to retrieve them embedded within my PHP-generated web pages.
When I test retrieving the stored images using
header('Content-type: ' . $image['mime_type']);
echo $image['file_data'];
everything looks just fine.
However, I have not yet found a way to retrieve the image(s) cleanly into the middle of my documents. For example, using
$image = $row['file_data'];
echo '<img src="data:image/jpeg;base64,'.$image['file_data'].'" alt="photo"><br>';
...or...
$im = imageCreateFromString($image);
I just wind up with a bunch of hexadecimal garbage on screen.
I intitially stored the Images using:
ob_start();
imagejpeg($resizedImage, null, 100);
$content = ob_get_contents();
ob_end_clean();
$sql = sprintf(
"insert into images (filename, mime_type, file_size, file_data, event_id)
values ('%s', '%s', %d, '%s',%d)",
mysql_real_escape_string($fileName),
mysql_real_escape_string($mimeType),
$imageSize,
mysql_real_escape_string($content),
$eventID
);
$result = $cn->query($sql);
Does anyone PLEASE have a working code snippet to successfully display the stored .jpg mid-file in the PHP output?
echo '<img src="data:image/jpeg;base64,'.base64_encode($image['file_data']).'" alt="photo"><br>';
However, remember that old IE versions do not support this kind of inline images! Besides that, the browser cannot cache such an image except together with its containing HTML page.
You should create some sort of "image server". You're already close to that.
For example, create something like image.php that will get a image name and will generate it on the fly.
So, for example, say you want to get somePic.jpg image. You can get it through:
image.php?name=somePic.jpg
<?php
header('Content-type: ' . $image['mime_type']);
echo $image['file_data'];
?>
Your tag:
<img src='image.php?name=somePic.jpg' />
Or more general:
echo "<img src='image.php?name={$image['filename']}' />"
Why not just call your test page image.php, then have it called from the browser on the rendered page:
<img src="image.php?imageid=123" alt="photo" />

How to display image from mysql blob in PHP (joomla)

I create a component in my joomla website. the component shows some photos (not big, only 8KB). the photos are stored in mysql blob. i can upload the photos to the joomla database but i cannot display it on the website. whatever i do it only show some encoding character or blank. I tried to create a separate page but but the result is same. Here is what i have done :
mycomp is my joomla component.
admin.mycomp.php
<?php
function showDetail($option)
{
$db = &JFactory::getDBO();
$id = mysql_real_escape_string(JRequest::getVar('id'));
$query = "select id,myphoto from jos_myphotos where id = ".$id;
$db->setQuery($query);
$rows = $db->loadObjectList();
HTML_myphoto::showPhoto($rows,$option);
}
?>
admin.mycomp.html.php
<?php
class HTML_myphoto
{
...
function showPhoto($row,$option)
{
...
header("Content-type: image/jpeg");
echo $row->myphoto; //this will show some encoding character
echo base64_decode($row->myphoto); //this will show blank page
//change echo with print get the same result.
...
}
...
}
I tried to create a separate page like this :
admin.mycomp.html.php
<?php
class HTML_myphoto
{
...
function showPhoto($row,$option)
{
...
?>
<img src="show_image.php?myphoto=<?php echo $row->myphoto;?>" width=200 height=300>
<?php
...
}
...
}
show_image.php
<?php
$myphoto = (isset($_GET['myphoto'])) $_GET['myphoto'] : false;
if($myphoto)
{
header("Content-type: image/jpeg");
echo $myphoto; //this will show some encoding character
echo base64_decode($myphoto); //this will show blank page
//change echo with print get the same result.
}
?>
the result is same.
I think you have 2 options:
Either you make an image tag with its source in a PHP file receiving only a ID parameter and retrieving the photo's string in the DB and echoing it.
Or you echo directly your photo's string in your tag:
<img src="<?php echo base64_decode($myphoto); ?>" />
EDIT
I just checked in an old app where I store the favicons in a DB. You don't need to base64_decode when you display your image inline (my option 2).
So FYI, this image works:
<img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAACkElEQVQ4y42TTWyUZRSFn/e+n6W00E4l9ScSCZGODXFLIIZENyZu1ITEGBdE3ejGVQksunDlwoUrE0ICCQuomZAYF4YNNvEPlFpjiJRgKq10HDKdmVJxEOh0vu+9h0UrMSyAk9zVOffczXPRI8hdciVNTZ/X6MjLOnrkK3XTLbk64lEK5FIhaf87HyqznYKy5qsLyuUPL/D1OXzkC8U4IhhViC9o7OAnSkkKksQDVG81GR//iAvTbS7OXIQQ1p0Oc3O/YlCAAAcSQIHIEc43Z8/z6r5xfrsiBp9+ArK4FgprNye//oEMDIJDMBDU6jc4d/YXzpz5kcuzC5SGBvBkoMT257ah5FTn/4Qgpqd+InM3LEDr+j8cO/45pyrnmLk0w0uv7KV/cIDCI4GIhUAgY3h4C9W5Kma9LF//l2xpqc33301xcuJLTp+ehLiJbSNlcpxoEanAolF4okB0lRAiuVOt1cje/+AAly8tcHWhDnEDeAfXKo/FTbg7ZLdwCrDI0PAAK7fvQATkYIbN/l4jWh8pAb4BrJ/abI32301MXULKoIhE9bKxt8RKJ4D1gXpIitj+d19j6PGN7CiXQavgHYir3G5fY+tT/Wx/cgulnh6su0JYvUPodiHvAGJz32YoJC222qo1lvTH1b906NBngq06cPBjFZKkXIuNmhZbN3RlvqUTlUnt2fumsGc0NvapkJLcpeRrzF+r31R5dLd2PP+i6s3if//gcndJUqPRUKVSUbPZFCnlkpJcSWmd+dffeE/BntWJk9/eW7q/RJJSSjIzQxKBhIUcgN17dhFCxsREheXlZSStZUIghEBRFACYGRlwz3Q5FuDtt/Yx/fMFSqVB8jwnrPP/Xy7LMtwdM+Mu+2gfA7SP0igAAAAASUVORK5CYII=" style="margin-right: 5px; vertical-align: middle;" class="bbns_itemDragger">
And it is stored in my DB like this (base64 encoded):
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAACkElEQVQ4y42TTWyUZRSFn/e+n6W00E4l9ScSCZGODXFLIIZENyZu1ITEGBdE3ejGVQksunDlwoUrE0ICCQuomZAYF4YNNvEPlFpjiJRgKq10HDKdmVJxEOh0vu+9h0UrMSyAk9zVOffczXPRI8hdciVNTZ/X6MjLOnrkK3XTLbk64lEK5FIhaf87HyqznYKy5qsLyuUPL/D1OXzkC8U4IhhViC9o7OAnSkkKksQDVG81GR//iAvTbS7OXIQQ1p0Oc3O/YlCAAAcSQIHIEc43Z8/z6r5xfrsiBp9+ArK4FgprNye//oEMDIJDMBDU6jc4d/YXzpz5kcuzC5SGBvBkoMT257ah5FTn/4Qgpqd+InM3LEDr+j8cO/45pyrnmLk0w0uv7KV/cIDCI4GIhUAgY3h4C9W5Kma9LF//l2xpqc33301xcuJLTp+ehLiJbSNlcpxoEanAolF4okB0lRAiuVOt1cje/+AAly8tcHWhDnEDeAfXKo/FTbg7ZLdwCrDI0PAAK7fvQATkYIbN/l4jWh8pAb4BrJ/abI32301MXULKoIhE9bKxt8RKJ4D1gXpIitj+d19j6PGN7CiXQavgHYir3G5fY+tT/Wx/cgulnh6su0JYvUPodiHvAGJz32YoJC222qo1lvTH1b906NBngq06cPBjFZKkXIuNmhZbN3RlvqUTlUnt2fumsGc0NvapkJLcpeRrzF+r31R5dLd2PP+i6s3if//gcndJUqPRUKVSUbPZFCnlkpJcSWmd+dffeE/BntWJk9/eW7q/RJJSSjIzQxKBhIUcgN17dhFCxsREheXlZSStZUIghEBRFACYGRlwz3Q5FuDtt/Yx/fMFSqVB8jwnrPP/Xy7LMtwdM+Mu+2gfA7SP0igAAAAASUVORK5CYII=
I'm sorry, did you skip some lines from show_image.php?!
Cause $myphoto is just the id of the photo. You can't base64_decode an ID.

Categories