0

I am drawing an image in a canvas and passing the canvas dataURL through AJAX to a PHP code to store it in Mongo DB gridFS.

While I am able to get the data URL and able to store the file but when I retrieve to show the image it does not show the image. My code snippet for storing is as below

$image = str_replace('data:image/jpeg;base64,', '', $_POST['dataurl']);

$decodedData = base64_decode($image);
try{
/*Get DB Connection for catagories document*/
$db = $this->registry->db->selectDB('myfiles');
// GridFS
$grid = $db->getGridFS();
$gridMetadata = array();
$gridMetadata['userid'] = $_POST['userid'];
$id = $grid->storeBytes($decodedData, $gridMetadata);
}
catch(MongoGridFSException $e){
echo $e;
}

to Display the image the code is

<?php
// Connect to Mongo and set DB and Collection
$mongo = new Mongo();
$db = $mongo->myfiles;
$gridFS = $db->getGridFS();
$image = $gridFS->findOne("IMG_0808.JPG");
header('Content-type: image/JPG');
echo $image->getBytes();
$mongo->close();
?>

I think I am not storing the file right. Where am I going wrong. Any help would be greatly appreciated

Shantanu
  • 13
  • 4

2 Answers2

0

You seem to be mixing methods here in your efforts to store from Base64 encoded data you receive in the request. If you want to refer to this by a "filename" later, which is what .findOne() is doing implicitly, then you need to store that "meta" information as well:

$image = str_replace('data:image/jpeg;base64,', '', $_POST['dataurl']);

$decodedData = base64_decode($image);
try{
    /*Get DB Connection for catagories document*/
    $db = $this->registry->db->selectDB('myfiles');
    // GridFS
    $grid = $db->getGridFS();
    $gridMetadata = array();
    $gridMetadata['filename'] = $_POST['filename'];    
    $gridMetadata['userid'] = $_POST['userid'];
    $id = $grid->storeBytes($decodedData, $gridMetadata);
}
catch(MongoGridFSException $e){
    echo $e;
}

So you will need a "filename" in your POST data to be able to assign the "filename" as a meta attribute.

Now in your later code you can call .findOne() on the grid store and it will match the "filename":

<?php
// Connect to Mongo and set DB and Collection
$mongo = new MongoClient();
$db = $mongo->myfiles;
$gridFS = $db->getGridFS();
$image = $gridFS->findOne("IMG_0808.JPG");
header('Content-Type: image/jpeg');
fpassthru($image->getResource());
$mongo->close();
?>

Making sure you get your "header" information correct so the client will recognize it.

As a hint, store the MIME type as additional metadata when saving and read it when retrieving. You can do a regular .find() on a standard collection object to read this as that is all it is to MongoDB. That should help your code not break for different image formats.

P.S Use MongoClient as the Mongo class is deprecated.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • I am adding the metadata as the unique username and retrieving using the same. my problem is not in finding the record. I am able to find it but not able to display it – Shantanu Jun 18 '14 at 02:41
  • @Shantanu Copy and paste gets me again. The missing part was the `getResource()` method and actually using `fpassthru()` to output the resource stream. Your call to `echo` just tries to "stringify" which would not be what you want. – Neil Lunn Jun 18 '14 at 02:54
  • Thanks Neil - let me try getResource() and revert – Shantanu Jun 18 '14 at 08:08
  • Problem is solved it was a problem with my php as it was trying to display JPEG as well as the other PHP generated HTML content. I put the JPEG code in a different PHP and called it as an URL of an image tag. Worked like a charm. Thanks Neil for some valuable inputs – Shantanu Jun 28 '14 at 21:44
0

Problem is solved it was a problem with my php as it was trying to display JPEG as well as the other PHP generated HTML content. I put the JPEG code in a different PHP and called it as an URL of an image tag. Worked like a charm. Thanks Neil for some valuable inputs

Shantanu
  • 13
  • 4