I am trying to display an image from a MySQL database on a webpage using PHP. I am aware that this is not the most efficient method, but still I would like to see how it is done....
To insert the image into the database I am using this code:
//Get File
File file = new File("C:\\Users\\blah\\blah\\blah\\WebcamImage\\" + name);
FileInputStream fileStream = new FileInputStream(file);
//Prepared Statement
pStmt = connection.prepareStatement("INSERT INTO table (webcamPic1) values (?)");
pStmt.setBinaryStream(1, fileStream, (int) file.length());
pStmt.executeUpdate();
To display the image on the website, I currently have this PHP code:
$result = mysqli_query($con,"SELECT * FROM table");
header('Content-Type: image/jpeg;');
echo "<table border='1' title='WEBCAM'>
<caption>WEBCAM</caption>
<tr>
<th>WEBCAM 1</th>
</tr>";
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['webcamPic1'] .
"</td>";
echo "</tr>";
}
echo "</table>";
mysqli_close($con);
On the webpage the file is displayed as a mess of symbols, like this:
ÿØÿàJFIFÿÛC $.' ",#(7),01444'9=82<.342ÿÛC
2!!22222222222222222222222222222222222222222222222222ÿÀz£!ÿÄÿÄC!1AQa"q2‘¡±Á#Bá3RÑðbrñ$4CSc¢s’“ÂÒÿÄÿÄ(!1AQa"2q‘¡ðBÿÚ?ûö„ã=–Ù0Xa˜#•7BÀÙ”BTà÷#DÂ.€Å¬´
7……Óc¨L1„¡£ì·2€Ä#?tû7A‘öTl¢ƒÂeEUn#BØ#r°#Â%TCŠ(€±#,±##„” RBÔB‘Â
}’¢µ!•HHá›'±'')DÝ”%#Í7 Ì((hTm¥)U æð¦[쨑6HE¾Pl%sA"æ[ÔûJ¨‹©OHh°7s
Iáp€Ñ¨":µþ¦³Ó÷5¨Ò¼Ñ©ÿí÷]'âäŸöG'àèVqw«ý&Çì¹êøY&'¡Y²ñ¹Wg)±Âï
‡·òYCÿ_¥4÷NÜ.m˜,ƒ„¨g²3öEdÃBžrº¿^·º á•Flˆ!5Õ„NxZ0ˆP…¯>ꨢ
¡Aº£eFYD-!E•)‚ÓÙ›!•Xª2^Pct§•B‘ tŽmÐ) e¨$B‹ÇQ¥•V¹Af:EøU”£
Kð®¡OµÒk 8)œ•r›lØýղТêRˆçÔm¡HÔp0,¹qàé[¢h~³kêäRË)vîîë·ãžØåßD«YpÕ«+ÑÆ9×
gƒž0ºü;\ÚÕ›Pá$C“Ð÷Sòðùqþ‰ÇŸÇ“Ó>Âg=Ö^z>UëL”Àñu0ÇdgªŠåü‘Y8„%0##dÃ(0ˆˆ¼
+| ל¦‚xEY„£÷TˆƒÙÁ[¿T-•” ìUYˆ?+ <#‰ESŽot‹€è(*Â4 E•jRBƒÂ ¸YEÌIÌ ¨°((×BèkïÑA#dvYX€”‰TIÀ©Pm·”ûP
Obviously I am doing something very wrong. What is the correct way to display the true image?
Thank you.
You are mixing two different contents in single HTTP response - it does not work that way and you cannot send HTML and images combined as HTTP does not support multiplexing (SPDY does for example). So this is wrong in the way you do it as browser does NOT expect this and is unable to separate one from the other considering all data it receives in this response as HTML document, hence garbage you seeing as it expects text and handles it all as such. To do this right way, you should have separate PHP script that will return image content, but the request for it should come from browser. So you should just return URL to your image script in SRC for image:
<img src="image.php">
and output image from image.php if so.
Also your code current code makes no sense from other reason too:
header('Content-Type: image/jpeg;');
echo "<table border='1' title='WEBCAM'>
since HTML is NOT image/jpeg type.
PS: storing images in database is considered very bad idea. Store images on disk and keep references to it in your db records only.
There is way to this try something like this:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />
data uri notation should do the job.
last part of the uri i base64 encoded image.
So You just should get Your image data from database encode it with base64_encode and then return it to the browser
For more details check this:
http://en.wikipedia.org/wiki/Data_URI_scheme
Related
okay so it is appearing to me my header() isn't doing anything. i tried moving it to the very top of the file instead nothing changed unless I put it in its own but then the rest of the file doesn't run but it does send the header.
EDIT: I updated my code with your suggestions, but it still isn't working correctly. Below is an image of the network tab when I inspect the page. The big thing I notice is the calls are being made but its fetching the same about of data for every image and its a very tiny amount of data.
edit: I am getting and Invalid URL Error when I inspect in chrome unless I remove data:image/png;base64,
Referrer Policy: strict-origin-when-cross-origin
I can't seem to get this working correctly. The png image should be pulling from the database and then displaying in the HTML. (and yes I know this isn't SQL injection safe) I assume there is some issue with it being called from the loop, but I am unsure. Or that it can't find the getImage.php to use it this way do i need to import it or something earlier in the code? It does correctly pull in the item_id. The result just gives me a broken image box. I know my getImage.php is outputting the correctly formatted image, because I have taken the output directly from there and inserted in place of the call for it and the image has show up. So it tells me this line below is my issue
echo ('<td><img src='"getImage.php?image_id="' . $row["item_id"].'"></td><td>');
if I edit as follows it works fine (but obviously it give me the same image for every entry) DBS is the decoded byte string that getImage.php outputs
echo ('<td><img src="data:image/png;base64,DBS"></td><td>');
PHP for the Front Facing page (blackmarket.php:
$sql="SELECT * FROM `item` WHERE 1";
$result = $link->query($sql);
echo("<table>");
if ($result->num_rows > 0) {
// output data of each row
echo("<tr>");
while($row = $result->fetch_assoc()) {
$newrow=0;
echo("<td>");
echo ('<img src="getImage.php?image_id='.$row['item_id'].'" />');
getImage.php:
<?php
require_once "connect.php";
if(isset($_GET['item_id'])) {
$sql = "SELECT item_img FROM item WHERE item_id=" . $_GET['item_id'];
$result = mysqli_query($link, $sql) or die("<b>Error:</b> I can't find the image <br/>" . mysqli_error($link));
$row = mysqli_fetch_array($result);
header("Content-type: image/png");
header("Content-Length: " . strlen($row["item_img"]));
echo $row["item_img"];
}
mysqli_close($link);
Just specify
echo "<td><img src=\"getImage.php?image_id={$row['item_id']}\"></td>";
The browser is responsible for assembling the page, and makes a separate call to the getImage.php script and reads the image data that you are returning.
Return the binary image data directly, along with the size. This might also be part of the problem.
<?php
require_once "connect.php";
if(isset($_GET['item_id'])) {
$sql = "SELECT item_img FROM item WHERE item_id=" . $_GET['item_id'];
$result = mysqli_query($link, $sql) or die("<b>Error:</b> I can't find the image <br/>" . mysqli_error($link));
$row = mysqli_fetch_array($result);
header("Content-type: image/png");
header("Content-Length: " . strlen($row['item_img']));
echo $row['item_img'];
}
mysqli_close($link);
Omit the closing php end tag ?> from this script. PHP best practices is to omit it for all scripts but it is especially important in a script like this that returns binary data, as a bit of whitespace or a UTF-8 BOM character can corrupt your output and is often hard to debug.
You are confusing two things:
data: URIs allow you to embed an image directly in the source code of an HTML page, so that the browser can render them immediately without another call to the server. They use base64 to make the data consist only of text, because you can't put non-text characters in the middle of your HTML source code
Normal https: URLs tell the browser to make a request to the server, which returns the image data, with no extra encoding needed. Most commonly, the web server will load the image straight from disk, but the browser doesn't know about that, so you can just as validly have a PHP script which returns the same data, based on whatever logic you want.
In your code, you've mixed the two: you've prefixed a normal URL with data:, so the browser is expecting the data right there in the source code, and never makes a call to getImage.php.
What you need to do instead is make sure that in your getImage.php you
echo out just the image data - no whitespace or debug output mixed in
not base64 encoded (if it's stored in the database that way, decode it before sending to the browser)
tell the browser it's an image with an appropriate Content-Type header, e.g. header('Content-Type: image/png'); - again, no mention of base64 encoding or anything else, you're serving an image just as if it was a file on your server
You shouldn't need to set the Content-Length header manually, the server will sort that out just like it would if you were outputting HTML
You can then load that image URL directly in the browser and it should display, no need to even look at your HTML until that part is working right.
Well I finally figured out what was going wrong. In my connect.php I had some white space and that white space was being called before my header so my header wouldn't work
I have uploaded an Image in my database. The datatype is BLOB. Now I want to view this image in my browser. I have written the following code but its not generating the image. Kindly check it.
Thanks
<?php
include 'connect.php';
//$id= $_GET['product_id'];
$query_images = "SELECT image FROM product_images WHERE product_id=121";
if (!$query_images_result = mysql_query($query_images))
{
echo mysql_error();
}
else
{
$fetch_images = mysql_fetch_array($query_images_result);
$print_images = $fetch_images['image'];
header('Content-type:image/jpeg');
echo $print_images;
}
?>
File 2
<body>
<img src='single_product_image_show.php' alt="image" />
</body>
maybe something like this? You might wanna use base64 encoding to build in the image
FYI: NOT TESTED.
$sql = "SELECT `image` FROM `product_images` WHERE `product_id`=121 LIMIT 1";
$query_images_result = mysql_query($sql);
if (!$query_images_result)
{
echo mysql_error();
}
else
{
list($print_images) = mysql_fetch_array($query_images_result);
$base64source = "data:image/jpeg;base64," . base64_encode($print_images);
echo '<img src="'.$base64source.'" alt="" />';
}
There are multiple possible reasons why this could happen. First try your script directly without "header('Content-type:image/jpeg');" so you can see what it actually returns. Like http://[youhostname]/single_product_image_show.php I assume you will see some errors.
Some best practices to serve images from php:
If you can remove the end php tag (?>). You don't actually need it and you can avoid issues when you have whitespace character after the close tag which will be written to the response and so results as a corrupt image.
You should specify the Content-Length header as well. It's not mandatory but the browser
will know how big the file it has to download.
Specify some cache control headers (https://en.wikipedia.org/wiki/List_of_HTTP_header_fields) so browsers can cache your image so it won't result a full page load and mysql query every time the image appears on the site.
You can store ETag and/or Last-modified in the database which you can retrieve and put in the headers.
I have a postgres database with stored images 'bytea' type and I try to display them into a browser with PHP. I found the way to display one of them but I can't make it for more than one. The code I use is the following:
File Name - display_image.php
$conn = pg_connect("dbname=test user=postgres password=postgres");
$temp = '/home/postgres/tmp.jpg';
$query = "select lo_export(image, '$temp') from map ";
$result = pg_query($query);
if($result)
{
while ($line = pg_fetch_array($result))
{
$ctobj = $line["image"];
echo "<IMG SRC=show.php> </br>";
}
}
else { echo "File does not exists."; }
pg_close($conn);
File Name - show.php
header("Content-type: image/jpeg");
$jpeg = fopen("/home/postgres/tmp.jpg","r");
$image = fread($jpeg,filesize("/home/postgres/tmp.jpg"));
echo $image;
The problem seems to be the "tmp.jpg" virtual file which displays only one image. If the result of the query is 7 images then it displays 7 times the same image within a while loop. How can I solve this?
Thanks for the interest!
I did this some time ago for bytea.
You need to run your bytea data through pg_unescape_bytea. See http://php.net/manual/en/function.pg-unescape-bytea.php
Basically your SQL query returns the bytea field in an escaped format.
However this is not what you are doing. And so the above is just for the next poor sap who comes here looking for bytea help. Please amend to note you are using LOB's not BYTEA's.
Also note that your code there is not concurrency safe. If two users request different images, my guess is that you will get both users getting different images. For this reason you should add the oid to the retrieval url, and name your file /tmp/$oid.jpg where $oid is the oid of the large object. You will need to retrieve that info (I believe it looks like it is stored in the image field of map?). On the other hand that assumes that all files are essentially public. if that's not the case, you want to move everything into the show_image.php and clean up when you are done.
I've create a table where I've saved images through "BLOB". I need to show those images along with other items. But I don't know how to show those images together in the same page.
Here's my php code that displays other things in form of a table. Similarily, I wanted to display images accordingly. Any help?
<?php
$display_query = mysql_query("SELECT * FROM eportal");
echo "<table id='pageTable'><thead><tr><th>Item code</th><th>Description</th><th>Cost</th></tr></thead>";
echo "<tbody>";
while($row = mysql_fetch_array($display_query)){
print "<tr><td>".$row['itemid']."</td><td>".$row['description']."</td><td>";
print "₹".$row['cost']."</td></tr>";
}
echo "</tbody>";
echo "</table>";
mysql_close($connection);
?>
Saving images to the DB is not a good idea but if You think You need to it this way, then You can retrieve the data from DB table, encode it to base64 (http://php.net/base64_encode) and then in HTML print it in this way:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
Using PHP You would write:
echo '<img src="data:'.$image_mime_type.';base64,'.base64_encode($image_data_from_db).'" alt="My image alt" />';
As other people mentioned, storing the images in the database is usually a bad idea.
Images are not transmitted in the same HTTP response with another page data.
To show images from the database, you would need to implement a script which, given the item id, would read the field and send the image's binary data; and provide the path to the script in your form's <img src="">:
while($row = mysql_fetch_array($display_query)){
print "<tr><td>".$row['itemid']."</td><td>".$row['description']."</td><td>";
print "₹".$row['cost']."</td><td>";
print "<img src=\"image.php?id=".$row['id']."\"></td></tr>";
}
image.php is another script which outputs the value of image_blob given the eportal.id. You would also need to provide correct size and mime type in the headers.
You better just store the images in a file (accessible by the web server) and store the path fo the file in the database.
Read the Blob data and write it into the file with header type image.. and try to print it, It should display the image file.
And yes saving image or any file in DB is really a bad habit as you are increasing DB size and it slowdown the performance also.. I suggest you to just try to convert you Blob into Image but don't apply in your work. Just save the image at desired location and keep its location path into DB to fetch and save next time.
The debate of storing blobs versus storing a path to the image file on disk has been debated over and over again. Microsoft provides a research paper comparing the pros and cons of each here. With that said, to display a blob as an image you need to make a call to a separate page and output header information that tells the browser what type of image is stored.
For example:
connectToDatabase();
$sql = "SELECT image_blob FROM eportal;";
$result = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($result);
header("Content-type: image/jpeg");
echo $row['image_blob'];
$db->close();
In case you still want to save your images in database, you will need second script which will get those images from database and pass them to browser with correct headers.
header("Content-type: image/jpeg");
#
# Replace this with database read:
# readfile('myimage.jpg');
Also, you will need to store what kind of image u use. There will be different header for JPEG, GIF or PNG file.
I'm trying to display multiple images using PHP and MySql database, even if using the while loop I don't get all of the images, I only get one, I mean the first one in the table. What's the problem ?
I'm using a table ID_IMAGE (int, pk, auto increment) and myImage (blob)
$query = mysql_query("SELECT myImage FROM image");
while($data=mysql_fetch_array($query)) {
header('Content-type: image/jpg');
echo $data['myImage'];
}
A possible way to solve this problem is to have a separate script to dynamically output the contents of the image eg. :
image.php
header('Content-type: image/jpg');
// DataBase query and processing here...
echo $data['myImage'];
and call it whenever you need to show images stored in your DB eg. inside your loop:
echo '<img src="image.php?id=' . $data['id'] . '">';
But storing images in the database will take a toll on your server and unless they're really small or you have a good reason to do so, you should only store their physical location on the disk.
You can also use this approach if you wish to hide image location from your users, or control access, but there are better and faster alternatives for that case.
Just to mention the possibility to embed the images directly in html by encoding them, you can use this:
$query = "SELECT myImage FROM image";
if ($result = mysqli_query($link, $query)) {
while ($row = mysqli_fetch_assoc($result)) {
echo '<img src="data:image/jpg;base64,' . base64_encode($row['myImage']) . '">';
}
}
Pro:
The browser does not need to load the images over an additional network connection
You can query and display multiple images in one request
Con:
If the image(s) are big and/or there will be many images, the page will be load slow
Encoding an image to base64 will make it about 30% bigger.
For more information about base encode images:
http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to/
base64 encoded image size