Welcome Guest, Not a member yet? Register   Sign In
Dynamic PNG creation using the output class - not working
#1

[eluser]ohall[/eluser]
Hi,

I'm creating an image dynamically using GD and trying to return the resulting image using the output class. I'm using the 2.0.2 build.

Following the documentation, I have this code:

Code:
class Img extends CI_Controller {

  function _remap( $id, $params = array())
  {
    //
    // Controller code to create the image
    //
    imagepng( $img, 'cache/tmp.png' );
    imagedestroy( $img );
        
    $this->output
        ->set_content_type( 'image/png' )
        ->set_output( file_get_contents( 'cache/tmp.png' ));
  }
}

The image is created no problem, so I'm happy that everything's fine up to the final output, but my browser returns the png data as plain text... not very useful.

I checked the data coming back from Apache, and can see the header is actually setting "Content-Type: text/html" - so no wonder I'm getting text rather than an image!

Can anyone tell me what I'm doing wrong?

Many thanks,
Oliver
#2

[eluser]osci[/eluser]
file_get_contents returns the contents of a file in a string

take a look at fread function. It might help you
#3

[eluser]Dao[/eluser]
Hallo, schön dich zu treffen! Ich zum ersten Mal diese Art von Forum, in der Hoffnung, zu einem späteren Zeitpunkt werden Ihre Führer! ! ! Vielen Dank! ! ! ! !
#4

[eluser]ohall[/eluser]
@osci: Hi Osci, thanks for the response - however, I'm not sure this will help, for the following reasons:

1) as I mentioned, my code fragment is functionally the same as the CI documentation, so I would hope file_get_contents() is an appropriate (and the best) function to use. Take a look at the current output class docs.

2) since the set_output() method of the output class assigns the passed value to a string internally, I would have said a string is exactly the right type to be passing. After all, a string (assuming we're not doing anything with multi-byte stuff) is just a block of bytes - whether it contains human readable text or image data is irrelevant.

3) passing the data isn't the issue. The browser is receiving the png file. The issue is the headers are being overridden somewhere - I ask for the image/png mime type but I'm given text/html.

I'm trying to use the CI framework "properly" so I'd really like to get the output class handling my image output.

Many thanks for the suggestion,
Ol
#5

[eluser]osci[/eluser]
try
Code:
->set_content_type('png');
to serve both image/png and image/x-png

You might need to change the headers too
#6

[eluser]ohall[/eluser]
Tried that too... it makes no difference.

I took a look at the output class code itself and the "png" or ".png" style just picks up the correct MIME type as defined in the mimes.php config file. Specifying anything of the form a/b simply adds that as the content type header.

The point is, the output class (I presume) is sending an incorrect Content-Type header and not honouring the type requested. Since I'm following the documentation example pretty much verbatim, I'm either doing something before calling the output class methods which is changing the behaviour of the class (i.e. have the headers already been sent before I specify the MIME type?) or the output class doesn't work as the documentation would have me believe.

I'm kind of hoping one of the development guys jumps in on this to set the record straight.

Thanks again Osci,
Ol

P.S. I've tried setting some headers manually too - though this is kind of what set_content_type does if you take a look at the class code. Still no difference, which is making me think something else is overriding the headers - I haven't tried to work out where they get written yet though!
#7

[eluser]ohall[/eluser]
Sorry to bump my own post, but I'm really stuck here.

I've even ended up modifying the core code slightly (I made the Output class headers array public) so I could see the headers before they get sent, and then output the headers along with the content.

Code:
$this->output->set_content_type( 'png' );
        
    if( count( $this->output->headers ) > 0 )
    {
        foreach( $this->output->headers as $header )
        {
            echo $header[0].'<br>';
        }
    }

    $this->output->set_output( file_get_contents( 'cache/tmp.png' ));

The output is a single header of:
Content-Type: image/png

Just what I was expecting. But Wireshark shows that the headers that are actually *sent* are totally different.

Code:
HTTP/1.1 200 OK
Date: Mon, 23 May 2011 22:36:55 GMT
Server: Apache
X-Powered-By: PHP/5.2.11
Content-Length: 2638
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html

Is there some config that I'm missing that forces PHP's header() (which is called by the Output class) function to be ignored? Could it be an Apache thing?
#8

[eluser]ohall[/eluser]
Just for more info... This works just fine on the same server, but outside of CI.

Code:
&lt;?php
header( "Content-Type: image/png" );
echo file_get_contents( 'cache/tmp.png' );
?&gt;




Theme © iAndrew 2016 - Forum software by © MyBB