views:

252

answers:

2

Hey,

I was wondering if there was a way for a controller to, instead of returning a string, or a view, return an image (be it JPG, PNG etc). For example, instead of ending with a $this->load->view('folder/special_view.php), I'd like to do something like $this->load->image('images/gorilla.png'), and have it so if my user were to go to that controller they would see an image as if they'd gone to a normal .png or jpeg. Can I set the headers so it expects a different MIME? Example code of this would be fantastic.

It would take forever for me to explain why I need this, but it involves bringing a premade CMS into codeigniter, and having it need certian things to be true. Thank you so much!

+4  A: 

sure you can, use this instead of $this->load->view()

$filename="/path/to/file.jpg"; //<-- specify the image  file
if(file_exists($filename)){ 
  header('Content-Length: '.filesize($filename])); //<-- sends filesize header
  header('Content-Type: image/jpg'); //<-- send mime-type header
  header('Content-Disposition: inline; filename="'.$filename.'";'); //<-- sends filename header
  readfile($filename); //<--reads and outputs the file onto the output buffer
  die(); //<--cleanup
  exit; //and exit
}

of course, you need to swap the mime-type in case the file is a png or gif

pǝlɐɥʞ
Works perfect, thanks!
Ethan
+1  A: 

This is not intended as One-upmanship, but pǝlɐɥʞ's suggestion is a pure PHP implementation that is not all that re-usable. You wanted to use the syntax $this->load->image('images/gorilla.png') so here is how you can.

Create /application/libraries/MY_Loader.php

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Loader Class
 *
 * Loads views and files
 *
 * @package  CodeIgniter
 * @subpackage  Libraries
 * @author   Phil Sturgeon
 * @category    Loader
 * @link     http://codeigniter.com/user_guide/libraries/loader.html
 */
class MY_Loader extends CI_Loader {

    function image($file_path, $mime_type_or_return = 'image/png')
    {
        $this->helper('file');

        $image_content = read_file($file_path);

        // Image was not found
        if($image_content === FALSE)
        {
         show_error('Image "'.$file_path.'" could not be found.');
         return FALSE;
        }

        // Return the image or output it?
        if($mime_type_or_return === TRUE)
        {
         return $image_content;
        }

        header('Content-Length: '.strlen($image_content)); // sends filesize header
        header('Content-Type: '.$mime_type_or_return); // send mime-type header
        header('Content-Disposition: inline; filename="'.basename($file_path).'";'); // sends filename header
        exit($image_content); // reads and outputs the file onto the output buffer
    }

There are a few ways you can use this:

Basic output (default is jpeg)

$this->load->image('/path/to/images/gorilla.png');

Send mime-type to use other image types

$this->load->image('/path/to/images/gorilla.jpg', 'image/jpeg');

Return the image

$image = $this->load->image('/path/to/images/gorilla.php', TRUE);

Just like $this->load->view, the 3rd parameter being set to TRUE means it will return instead of directly outputting.

Hope this helps :-)

Phil Sturgeon
wow! thank you!
Ethan