How to get image back from GridFS?

3,677 views
Skip to first unread message

Andrew

unread,
Sep 1, 2011, 7:31:25 AM9/1/11
to mongodb-user
Hi. I managed to upload it with php, it works well. But now, how can I
get it back? Suppose these images are users' profile pictures, can't I
just embed a link to the db? Am I missing something?

I tried like this:
$obj=new MongoId('4e5f6ad381460ad005000004');
$storedfile=$grid->get($obj);

But now I have a MongoGridFSFile Object, how can I see the image and
embed it in a IMG tag?

Thanks a lot :)

Andrew

unread,
Sep 1, 2011, 7:36:14 AM9/1/11
to mongodb-user
I learned I have to getBytes(), but now it shows the bytes, how can I
get a real image back?

Nat

unread,
Sep 1, 2011, 7:40:32 AM9/1/11
to mongod...@googlegroups.com
Take a look at http://learnmongo.com/posts/getting-started-with-mongodb-gridfs/
--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.

Andrew

unread,
Sep 1, 2011, 7:52:30 AM9/1/11
to mongodb-user
I did that but now I have a new issue:

The image “http://localhost/img/image.php” cannot be displayed
because it contains errors.

Why is this? It's a good image, it's one of Window's pictures.

Code below:
$mongo = new Mongo();

$db = $mongo->bb;
$obj=new MongoId('4e5f70b681460ad00500000a');

$grid = $db->getGridFS();
$storedfile=$grid->findOne(array('_id'=>$obj));

header('Content-type: image/jpeg');
echo $storedfile->getBytes;


On Sep 1, 2:40 pm, "Nat" <nat.lu...@gmail.com> wrote:
> Take a look athttp://learnmongo.com/posts/getting-started-with-mongodb-gridfs/

Andrew

unread,
Sep 1, 2011, 8:04:51 AM9/1/11
to mongodb-user
fixed, getBytes was not a function, I should've written getBytes().

Thanks a lot!

Harsha

unread,
Sep 21, 2011, 11:29:29 PM9/21/11
to mongodb-user
Hello All,
I followed the link sent by Nat and yet I ran in to trouble.
Here's the error message
"The image “http://localhost:8080/SchemaRecipe/
DisplayRecipe.php?id=4e7aa9846803fadd4900000e” cannot be displayed
because it contains errors."

Please advice.

Dan Crosta

unread,
Sep 21, 2011, 11:40:07 PM9/21/11
to mongod...@googlegroups.com
Try removing or commenting the line "header(...)", or change the content type to "text/plain". If it is working, you should get a jumble of data in your browser; if it is printing an error (the more likely case), you will be able to read the error and fix the root cause.

- Dan

Harsha

unread,
Sep 21, 2011, 11:50:02 PM9/21/11
to mongodb-user
Thanks a lot for quick response Dan. It prints the byte characters
when I remove the "header(...)".
FYI, I'm trying to display a jpeg.
Please advice.

-Harsha

Dan Crosta

unread,
Sep 21, 2011, 11:57:06 PM9/21/11
to mongod...@googlegroups.com
Are you printing or echoing anything other than in the last line in the code you pasted?


- Dan

Harsha

unread,
Sep 22, 2011, 12:01:52 AM9/22/11
to mongodb-user
Hello Dan,
The result is same regardless of what I use (Print/Echo)
Here below is the code that I have:

$gridFS = $db->getGridFS();
$image = $gridFS->findOne(array('_id' =>
$val));
header("Content-Type: image/jpeg");
echo $image->getBytes();

please advice.

-Harsha

Dan Crosta

unread,
Sep 22, 2011, 12:07:36 AM9/22/11
to mongod...@googlegroups.com
Let's make sure the file got into GridFS correctly. In your terminal, do:

   mongofiles -d yourdb list

where "yourdb" is the name of your databsae. You should see your file there. To verify that it was added correctly without corruption, you can "download" the file with:

    mongofiles -d yourdb get yourfilename.jpg

Once you do that, can you open the file you "downloaded" successfully? If not, it probably wasn't added to GridFS correctly.

- Dan

Harsha

unread,
Sep 22, 2011, 12:26:34 AM9/22/11
to mongodb-user
I checked that in the first place to make sure I'm not missing
something fundamental. I have the file saved into the GridFS and I can
open the file when I retrieve the file from the GridFS. I see the
error only when I add the Header content of image type.

-Harsha

Harsha

unread,
Sep 22, 2011, 12:30:01 AM9/22/11
to mongodb-user
Correction:

In my previous post I meant to say that, I saved the file from the
program and was able to retrieve it from the terminal but not from the
program. When I try from the Program with out the header content
function I can see bytes printed on the screen but if I define the
header content of type image then it just blows up.

Please advice

-Harsha

Dan Crosta

unread,
Sep 22, 2011, 12:33:41 AM9/22/11
to mongod...@googlegroups.com
This might be silly, but are you certain it's a JPEG image? There are other content types for the different image formats.

- Dan

Asoka Sampath Edussooriya

unread,
Sep 22, 2011, 12:37:50 AM9/22/11
to mongod...@googlegroups.com
Hi Harsha,

Check the file and verify the extension of the file first

Thanks!

Asoka
Asoka Sampath Edussooriya

Harsha

unread,
Sep 22, 2011, 12:42:08 AM9/22/11
to mongodb-user
The file has a .jpg extension, I tried the content type "image/jpg"
and "image/jpeg" and neither one worked.
Please advice.

-Harsha

On Sep 22, 12:37 am, Asoka Sampath Edussooriya <eas...@gmail.com>
wrote:
> Hi Harsha,
>
> Check the file and verify the extension of the file first
>
> Thanks!
>
> Asoka
>

Asoka Sampath Edussooriya

unread,
Sep 22, 2011, 12:47:26 AM9/22/11
to mongod...@googlegroups.com
Remove the header and verify whether you get any result for the search.

Thanks!

Asoka

Harsha

unread,
Sep 22, 2011, 12:49:56 AM9/22/11
to mongodb-user
I have tried that. As I mentioned in my earlier posts, I see bytes
printed on the browser when I remove the header but when I include the
header I have the trouble.

-Harsha

On Sep 22, 12:47 am, Asoka Sampath Edussooriya <eas...@gmail.com>
wrote:
> Remove the header and verify whether you get any result for the search.
>
> Thanks!
>
> Asoka
>

Zoom.Quiet

unread,
Sep 22, 2011, 1:05:14 AM9/22/11
to mongod...@googlegroups.com
i usage nginx mod_gridfs :

server {
listen 9029;
location / {
gridfs static_files field=filename type=string;
mongo 127.0.0.1:27017;
}
}

su i an download img from mongo,
see: mdirolf/nginx-gridfs - GitHub
https://github.com/mdirolf/nginx-gridfs

2011/9/22 Harsha <srihars...@hotmail.com>:

...


--
人生苦短, Pythonic! 冗余不做,日子甭过!备份不做,十恶不赦!
俺: http://about.me/zoom.quiet
文字协议: http://creativecommons.org/licenses/by-sa/2.5/cn/

Sam Millman

unread,
Sep 22, 2011, 4:04:52 AM9/22/11
to mongod...@googlegroups.com
Try downloading the file from gridfs, see if it will display in your native OS image viewer.

It could be possible that the image really is corrupt.

Did you upload a dynamic image or one from a users library?

Also try not querying with _id. I have had problems with querying on _id before. Make a new field called "name" and put something random in there and query on that.

If that still don't work there is a 70% chance your image is corrupted.

2011/9/22 Zoom.Quiet <zoom....@gmail.com>

--

Harsha

unread,
Sep 22, 2011, 11:15:33 AM9/22/11
to mongodb-user
The file is viewable when I retrieve and save it from the GridFS via
terminal.
Yes, I have tried using the filename instead of _id to query and yet
it doesn't work.
I use Apache 2.2 as the server. Is it possible that the issue is
because of server settings?
Or could it be a randomly occurring bug in Mongo 1.6.3?

On Sep 22, 4:04 am, Sam Millman <sam.mill...@gmail.com> wrote:
> Try downloading the file from gridfs, see if it will display in your native
> OS image viewer.
>
> It could be possible that the image really is corrupt.
>
> Did you upload a dynamic image or one from a users library?
>
> Also try not querying with _id. I have had problems with querying on _id
> before. Make a new field called "name" and put something random in there and
> query on that.
>
> If that still don't work there is a 70% chance your image is corrupted.
>
> 2011/9/22 Zoom.Quiet <zoom.qu...@gmail.com>
>
>
>
>
>
>
>
> > i usage nginx mod_gridfs :
>
> > server {
> > listen 9029;
> > location / {
> > gridfs static_files field=filename type=string;
> > mongo 127.0.0.1:27017;
> > }
> > }
>
> > su i an download img from mongo,
> > see: mdirolf/nginx-gridfs - GitHub
> >https://github.com/mdirolf/nginx-gridfs
>
> > 2011/9/22 Harsha <sriharshared...@hotmail.com>:

Matt

unread,
Sep 22, 2011, 12:15:21 PM9/22/11
to mongodb-user
Try setting the content length header as well. Here's a snippet that
is working for us for png files:

$gridfs = $db->getGridFS();
$gridfile = $gridfs->findOne(array('filename'=>$filename));
$filedata = $gridfile->getBytes();

header("Content-Length: " . strlen($filedata));
header("Content-Type: image/png");
ob_clean();
echo($filedata);

Harsha

unread,
Sep 22, 2011, 3:18:23 PM9/22/11
to mongodb-user
Hello Matt, You suggestion was helpful. It works with png but doesn't
with jpeg. I have tried changing the Content-Type to image/jpeg.
Please advice.

-Harsha

On Sep 22, 12:15 pm, Matt <m...@ziplinegames.com> wrote:
> Try setting the content length header as well. Here's a snippet that
> is working for us for png files:
>
> $gridfs = $db->getGridFS();
> $gridfile = $gridfs->findOne(array('filename'=>$filename));
> $filedata = $gridfile->getBytes();
>
> header("Content-Length: " . strlen($filedata));
> header("Content-Type: image/png");
> ob_clean();
> echo($filedata);
>
> > > > 2011/9/22Harsha<sriharshared...@hotmail.com>:
> > > > > I have tried that. As I mentioned in my earlier posts, I see bytes
> > > > > printed on the browser when I remove the header but when I include the
> > > > > header I have the trouble.
>
> > > > > -Harsha
>
> > > > > On Sep 22, 12:47 am, Asoka Sampath Edussooriya <eas...@gmail.com>
> > > > > wrote:
> > > > >> Remove the header and verify whether you get any result for the search.
>
> > > > >> Thanks!
>
> > > > >> Asoka
>
> > > > >> On Thu, Sep 22, 2011 at 10:12 AM,Harsha<sriharshared...@hotmail.com
> > > > >wrote:
>
> > > > >> > The file has a .jpg extension, I tried the content type "image/jpg"
> > > > >> > and "image/jpeg" and neither one worked.
> > > > >> > Please advice.
>
> > > > >> > -Harsha
>
> > > > >> > On Sep 22, 12:37 am, Asoka Sampath Edussooriya <eas...@gmail.com>
> > > > >> > wrote:
> > > > >> > > HiHarsha,
>
> > > > >> > > Check the file and verify the extension of the file first
>
> > > > >> > > Thanks!
>
> > > > >> > > Asoka
>
> > > > >> > > On Thu, Sep 22, 2011 at 10:00 AM,Harsha<
> > > > sriharshared...@hotmail.com
> > > > >> > >wrote:
>
> > > > >> > > > Correction:
>
> > > > >> > > > In my previous post I meant to say that, I saved the file from the
> > > > >> > > > program and was able to retrieve it from the terminal but not from
> > > > the
> > > > >> > > > program. When I try from the Program with out the header content
> > > > >> > > > function I can see bytes printed on the screen but if I define the
> > > > >> > > > header content of type image then it just blows up.
>
> > > > >> > > > Please advice
>
> > > > >> > > > -Harsha
>

Dan Crosta

unread,
Sep 22, 2011, 4:17:09 PM9/22/11
to mongod...@googlegroups.com
You're saying it works if you set the Content-Type header to "image/png" but not when you set it to "image/jpeg"? That means your image is a PNG, not a JPEG, probably.

Your best bet is to record the content-type of the file when a new file is added (you can infer the content-type from the file extension, or there may be libraries in PHP which can infer the content type from the file data itself). You can do this using the $extra optional parameter to the storeFile method, or the $metadata optional parameter to storeUpload. I suggest you name the content-type metadata field "contentType" as this is conventional and works with other GridFS tools and drivers.

Once you've saved this metadata, you can access it though the "file" attribute of the MongoGridFSFile:

       $gridfs = $db->getGridFS();
       $gridfile = $gridfs->findOne(array('filename'=>$filename));

       header("Content-Length: " . $gridfile->getSize());
       header("Content-Type: " . $gridfile->file["contentType"]);
       ob_clean();
       echo($gridfile->getBytes());


(I've also used the getSize() method instead of computing the strlen of the data in this example)

- Dan

Harsha

unread,
Sep 22, 2011, 5:13:06 PM9/22/11
to mongodb-user
Ah! It works when I set the content type just like you mentioned Dan.
Thanks Dan, Matt and All for helping me.

-Harsha

abhishek...@gmail.com

unread,
Oct 17, 2017, 5:28:24 PM10/17/17
to mongodb-user






<?php
require_once('vendor/autoload.php');

try
{
// open connection to MongoDB server

$db = (new MongoDB\Client)->Image->photo;

//$gridfile = '';

if (isset($_FILES["image"] )) 
{
$questionCover = $_FILES["image"];
    $document = array(
//"type" => "MCQ",
"image" => new MongoDB\BSON\Binary(file_get_contents($questionCover["tmp_name"]), MongoDB\BSON\Binary::TYPE_GENERIC),
);
$ret= $db->insertOne($document);
$result = $db->find();
}
} catch (MongoConnectionException $e) {
        die('Error connecting to MongoDB server');
    } catch (MongoException $e) {
        die('Error: ' . $e->getMessage());
    }
?>

<html lang="en">
<head>
<meta charset ="UTF-8">
<title> Table.</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
</head>
<body>

<table>
<?php
  //  $i=1;
    foreach($result as $storedfiles) {
    ?>
    <tr>
        <td width="10"><strong><?php //echo $i; ?></strong></td>
        <td width="10">
            <?php //echo $storedfiles["_id"]; ?>
            <?php echo "Id :".$storedfiles["_id"]; ?>
            <?php header('Content-type: image/jpg'); echo "Image :".$storedfiles["image"]; ?>
            <?php  // $image = $gridFS->findOne(array('_id' => new MongoId($storedfiles["image"])));
$stream = $result->getResource();
            //echo $result->getBytes();
    ?>


        </td>
    </tr>
    <?php
    //$i++;
    }
    ?>
    </table>

   </body>
   </html>

Please suggest the Code to retrieve the image using php  , It is been uploaded in MongoDB

Abhishek 

Jeremy Mikola

unread,
Oct 18, 2017, 11:17:49 AM10/18/17
to mongod...@googlegroups.com
Please note that the thread you've replied to a thread from six years ago, which also refers to the API from the legacy "mongo" extension. The GridFS implementation in the current MongoDB PHP Library has a different API and is introduced in this tutorial.

That said, I can walk through your code and point out some errors and misconceptions:
  • At the top of the script, you check if $_FILES["image"] is set and conditionally insert a new document into the "photo" collection in the "Image" database. The document you insert only includes an "image" field, which you assign as a BSON binary value containing the bytes of that image. The driver will also generate an "_id" field with a new ObjectId, but note that you're not storing any additional information about the file (e.g. file name, MIME type).

  • You then call MongoDB\Database::find(), which will return a MongoDB\Driver\Cursor object. As noted in the Find Many Documents tutorial, iterating on the Cursor with foreach will yield result documents.

  • Both the insertOne() and find() methods are called within a try/catch block, but the exceptions you are catching are from the legacy driver. The documentation for the PHP library and the "mongodb" extension discusses exceptions that may be thrown, all of which are in either the MongoDB\Driver\Exception or MongoDB\Exception namespace (note that there is an inheritance hierarchy, so you can get by with only catching parent exception classes). MongoDB\Driver\Exception\RuntimeException should be sufficient for catching an error connecting to or communicating with the server.

  • While iterating on the Cursor as you produce HTML output, you are calling header(). According to PHP.net's own documentation, that function must be called before any output is generated by the script. You are also assuming the MIME type is "image/jpg", which may not be the case. There are numerous strategies for detecting the type of an image file in PHP. The most reliable will inspect the image's bytes (exit_imagetype()) instead of assuming based on the file extension.

  • After the call to header(), you proceed with printing the image's file contents (i.e. raw bytes). Unless you are using a Data URI scheme with an <img> tag (e.g. <img src="data:...">), you likely do not want to read and print the image bytes with HTML. A more appropriate solution would be to create a second script that serves the raw image data (with the appropriate Content-Type header), as described in this answer to How do I echo an image with PHP on Quora. In that case, the second script should likely accept the image file's ObjectId as a 24-character hexadecimal string, so it can look up the image. Additionally, that will mean that the main script rendering HTML no longer needs to read each image's file contents, so you can specify a query projection to ignore the "image" field containing binary data.

  • Lastly, you had some code calling $result->getResource(). By default, the PHP library will deserialize BSON documents as a MongoDB\Model\BSONDocument class, which is a thin wrapper around PHP's ArrayObject class. Calling getResource() hear tells me that you are again mixing up the new library with the legacy driver (likely MongoGridFSFile::getResource()).

Based on the code you shared, it's clear that you are not using GridFS at all. GridFS utilizes a specific two-collection schema and has the advantage of being able to store large files across multiple documents and track additional metadata such as filename, content hashes, upload date, etc. Additionally, all drivers provide a consistent API for accessing those files.

Your code is simply storing BSON binary values in arbitrary documents. While that isn't GridFS, it is also a perfectly valid use case and is not a problem (provided you're aware of the fact that this isn't GridFS and the API documentation for GridFS does not apply).



For other MongoDB technical support options, see: https://docs.mongodb.com/manual/support/
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user+unsubscribe@googlegroups.com.

To post to this group, send email to mongod...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages