Reputation: 77
I'm having a problem getting my images to display after extracting them from a database. I have 2 separate tables, one for the meta data and another to hold the actual blob data. that table is a regular BLOB and i only store 60k chunks of data in each row. I recompile the image when i want to render it.
i keep getting this error though:
the image "http://imgStore.localhost/ImageBuilder/index/id/11" cannot be displayed because it contains errors.
here is how the flow works however.
/Images/image/id/11 will have an image inside of it like this
<img src="http://imgStore.localhost/ImageBuilder/index/id/11" />
the Images controller handles insertions and edits as well as listing the images while ImageBuilder is only concerned with displaying a given image
here is the table structure:
images ------
image_id INT
image_name VARCHAR
image_type VARCHAR
image_size INT
loaded_date DATETIME
image_data --
image_data_id INT
image_id INT
data BLOB
here is how i save the file into the database:
( NOTE: i'm using the latest Zend Framework )
( insertion action ) ------------------
$image = new ImgStore_Model_Images($form->getValues());
$image->setImage_size(((int) substr($form->image_file->getFileSize(), 0, -2) * 1024));
$image->setImage_type($form->image_file->getMimeType());
$image->setLoaded_date(time());
$image->setLoaded_by($user->get('contacts_id'));
$mapper = new ImgStore_Model_ImagesMapper();
$image_id = $mapper->save($image);
// open the uploaded file to read binary data
$fp = fopen($form->image_file->getFileName(), "r");
$dataMapper = new ImgStore_Model_ImageDataMapper();
// loop through the file and push the contents into
// image data entries
while( !feof($fp) ){
// Make the data mysql insert safe
$binary_data = addslashes(fread($fp, 60000));
$data_entry = new ImgStore_Model_ImageData();
$data_entry->setImage_id($image_id);
$data_entry->setImage_data($binary_data);
$dataMapper->save($data_entry);
}
fclose($fp);
and here is how it is extracted:
(action) ------------------
$this->_helper->_layout->disableLayout();
// get the image meta data
$image_id = $this->_request->getParam('id', '0');
$mapper = new ImgStore_Model_ImagesMapper();
$info = $mapper->getInfo($image_id);
// build the image and push it to the view
$mapper = new ImgStore_Model_ImageDataMapper();
$this->view->image = $mapper->buildImage($image_id);
$this->view->name = $info->getImage_name();
$this->view->type = $info->getImage_type();
$this->view->size = $info->getImage_size();
(model) ------------------
public function buildImage($image_id)
{
// get the image data
$sql = "SELECT image_data
FROM image_data
WHERE image_id='$image_id'
ORDER BY image_data_id ASC";
$results = $this->_adapter->fetchAll($sql);
// piece together the image and return it
$image = NULL;
foreach( $results as $row ){
$image .= $row['image_data'];
}
return $image;
} #end buildImage function
(view) ------------------
<?php
header( "Content-Type: " . $this->type );
header('Content-Disposition: inline; filename="'.$this->name.'"');
echo $this->image;
?>
i have tried to use an image that was small enough to take up only one row in the image_data table as well, so i don't believe it has anything to do with the recompilation of the image_data rows.
any help would be appreciated, i truly have no idea what is wrong with this.
edited some formatting for display purposes.
Upvotes: 1
Views: 2789
Reputation: 1652
I recently did something like this but used a different approach for the rendering. Zend won't fire up the app if the request URI to an actual file, so I created a render action in my file controller that created a copy of the image on the drive. This makes scaling and management much easier since the files are all in one central db, but also gives the performance benefits of reading from the disk. Here's my open action:
public function openAction() {
$file = // find the file in the db
if(! $file) {
throw new Zend_Exception('File not found', 404);
}
$path = // get the filepath
if(! file_exists($path) || $this->_request->getParam('reload') == true) {
file_put_contents($path, $file->image_data);
}
$this->_redirect('document root relative path');
}
Upvotes: 1
Reputation: 1254
there's no real value in cluttering up the database with image data. (Fetching the data from the database will also be significantly slower than simply loading it off disk)
I suggest that you just store the images on the file system, and store the path to the image in the database alongside the meta data.
Upvotes: 0