tags:

views:

192

answers:

4

I'm looking at this code and have been through the docs but still don't understand how this should work. The code works fine just as it sits but I'm wondering if I should be outputting the header as png instead of jpeg.

What exactly is going on in this code? Is the png image converted to jpeg?

What I ultimately want to do is to watermark all gif, jpg, bmp and png images in a single directory. I'm outputting all headers, regardless of the image type as jpg. Is this correct? I hope I'm making sense here, I'm kind of tired.

$im2 = imagecreatefrompng($image)
imagecopy() and more code here
header("Content-Type: image/jpeg");
imagejpeg($im2,'',50);
+2  A: 

What your code does is more or less as follows:

// Load the PNG file from disk into memory
$im2 = imagecreatefrompng($image) 

$im2 is now a resource, referencing a image. Once in memory, it is not a png or a jpeg; it is a raw, uncompressed data. The "format" of an image specifies how that raw data is packaged and formatted; at this point, it has no such formatting. It's just data in memory.

// Some code which works with the image in memory, adding your watermark?
imagecopy() and more code here

// Tell the browser that we're output a JPG
header("Content-Type: image/jpeg");

If you request a jpg (ie http://host.com/image.jpg) then the server takes care of writing this header for you. If you're making a JPG on the fly via PHP you have to manually output the header. Otherwise, PHP assumes you're writing HTML and outputs the appropriate headers for you as soon as write anything to stdout, either via echo or just by having text/whitespace outside of <?php ?> tags.

// compress as a jpeg, and send to browser
imagejpeg($im2,'',50);

imagejpeg takes the raw image, compresses it as a jpg, and writes it to either a file (if you give it a filename) or stdout (which sends it to the browser). Technically to output to the browser, the 2nd argument should be null, not ''. The final parameter, 50, specifies the jpeg quality as percentage. 100 is high-quality, 0 is low quality.

meagar
Oh, OK.. If I'm understanding correctly, because the image that is saved on the server is in a raw format, then the image that it is outputting is in fact a jpg. Correct?
timmay
BTW: thanks for the great explanation.
timmay
@timmay: No, because `imagejpeg` is used, the image is outputted as a jpeg format. If `imagepng` would of been used at the end, the output format would of been png.
Andrew Moore
Thanks Andrew. Let me try this again.. So if we have an original pic that is a png image. We then use imagecreatefrompng($image) to convert?? or manipulate?? it. The image is then stored on the server in a raw format then we output the header as jpg and finally use imagejpeg(). By using imagejpeg, doesn't this in fact make a jpg out of our original image? Maybe better stated... It creates a copy?? of the png in a jpg format.
timmay
You say "The image is then stored on the server in a raw format"; this implies it's stored on disk. Once `imagecreatefrompng` is called, everything happens in memory. The original png file is uncompressed and copied to memory. No files are written to disk, all the image processing happens in memory. Finally, the script outputs the image data by passing it through `imagejpeg`, which compresses the data as a jpeg image and sends it to the browser. Again, nothing is written to disk.
meagar
Got it. Thanks. My only concern here is even after the png or gif image has been copied to memory then outputted to the browser, the file extension in the URI still remains png and I was wondering if I should create a function for every filetype and output the proper header that matches that extension. If it even matters.
timmay
If you want to make the output a little friendlier, you could include a content-disposition header to specify a filename with the proper extension. See http://php.net/manual/en/function.header.php
meagar
Thanks Meagar, you've been very helpful as have all the others. I'll check the link you provided for more info.
timmay
A: 

The imagejpeg function outputs the image in JPEG format regardless of the format of the original object. If you want to preserve the original format you need to determine this when loading the file and then use a different function when producing output - There are functions imagepng, imagegif, etc.

alxp
Thanks Alxp. So the file extension, even though it is still png even after the browser outputs the image, is ok?
timmay
I'm just wondering if I should create a function for every file type and output the headers that match the extension.
timmay
A: 

The code is loading an image into a GD resource from a PNG file, then manipulating it, and finally outputting the image in a different format (JPEG) to the browser.

When you call imagecreatefrompng, you're not just specifying that GD should use that file as its current working copy of the image, you're telling it to read the file, decode it from the PNG format, and load it into memory in some unknown internal format. At this point, the format of the file that the image was originally read from no longer matters. When you output it, you have to specify the format you want, since it no longer has a format associated with it. This is why you're using imagejpeg.

Will Vousden
Ok, thanks. This is exactly what Megar said. Let me ask you this then. If the original image that was being manipulated is a png image, when the browser outputs the image to browser, the extension is still png. Does this matter?
timmay
The extension of the file is still '.png', yes, but you're not outputting the file. You're outputting the in-memory copy of the image, which is completely separate frome the file. The browser has no knowledge of what the file's extension was.
Will Vousden
Ok, that was really my only concern here. So I don't need to create a different function for each type of file that I output. That is great news actually. Thanks Zakalwe.
timmay
A: 

The imagecreatefrompng is loading the image data from a PNG file. The image data at that point is just GD-specific pixel data.

The imagejpeg outputs the pixel data as a jpeg. So your header should be specifying jpeg in this case.

Matt