views:

451

answers:

3

Having only a valid GD image resource is it possible to find out the type of the original image?

For instance:

$image = ImageCreateFromPNG('http://sstatic.net/so/img/logo.png');

Can I get the original image type (PNG) having only the $image variable available?

+4  A: 

I don't think so, no. $image is in GD's internal image format after it has been processed by the ImageCreate() function.

Pekka
Thanks Pekka. Unfortunately I also don't think so, but I'm gonna wait a little longer to see if anyone can come up with a way to do this.
Alix Axel
What's the background? Maybe there is a different workaround to your problem?
Pekka
This is correct - the image is in GD's internal format so that it can be outputted into any available format. The only way to detect format is to use the original image file.
adam
@Pekka: Check my comment on Gordon answer.
Alix Axel
@adam: I'm pretty sure of that also, I'll wait until this question has 50 views or so just to make sure there isn't a working method that involves black magic. =)
Alix Axel
+1  A: 

I am not sure if it can be done from the $image variable, but to get the MimeType, you can usually use any of the four:

// with GD
$img = getimagesize($path);
return $img['mime'];

// with FileInfo
$fi = new finfo(FILEINFO_MIME);
return $fi->file($path);

// with Exif (returns image constant value)
return exif_imagetype($path)

// deprecated
return mime_content_type($path);

From your question description I take you want to use a remote file, so you could do something like this to make this work:

$tmpfname = tempnam("/tmp", "IMG_"); // use any path writable for you
$imageCopy = file_get_contents('http://www.example.com/image.png');
file_put_contents($tmpfname, $imageCopy);
$mimetype = // call any of the above functions on $tmpfname;
unlink($tmpfname);

Note: if the MimeType function you will use supports remote files, use it directly, instead of creating a copy of the file first

If you need the MimeType just to determine which imagecreatefrom function to use, why not load the file as a string first and then let GD decide, e.g.

// returns GD image resource of false
$imageString = file_get_contents('http://www.example.com/image.png');
if($imageString !== FALSE) {
    $image = imagecreatefromstring($imageString);
}
Gordon
Nope, that is not what I want since I don't have access to the path. =\
Alix Axel
But you do have access to *some* path, do you?
Gordon
No he doesn't, only to the opened image resource itself.
Pekka
@Pekka The image resource has to come from somewhere. In his example, he is using a URL. So even if he does not have access to the file on the remote server, he can copy the file to his server first and determine the MimeType from there
Gordon
@Gordon: The example is only an example, in my usage scenario a class constructor will receive a image resource and I want that same constructor to determine whether the resource is a PNG image. This constructor has no way of knowing the path to the original image.
Alix Axel
Oh and for the record, both `getimagesize()` and `exif_imagetype()` work with remote files. =)
Alix Axel
@Alix Ok, but I guess that still leaves the possibility to simply use any of the above to determine the MimeType when creating the resource and pass it to the constructor along with the image resource. While the MimeType is not determined inside your constructor then, it will be available at least.
Gordon
@Gordon, sure! I was looking for a way to not having to keep passing the type but that is most certainly going to be my only option.
Alix Axel
@Alix Another option could be to do whatever you need to do with the image resource and when done return it to the code that created the class and handle MimeType based stuff from there.
Gordon
A: 

You could just try loading the resource with the png loader, and if it's not a png image, it will fail, returning FALSE. Then just repeat with each of the valid formats you want to have, and if all fail, then display an error.

Tor Valamo
Opening the resource isn't a problem...
Alix Axel