First quesiton on Stack Overflow, so please be gentle.
What I'm trying to do is simple and should be very straightforward in my mind. The results have been less than encouraging. What I'm trying to do: I have a web page that receives base64-encoded PNG image data. I can and have successfully taken that data through the proper steps to create an image on the filesystem. Call this "Script A":
$imageData = $_POST['png'];
$imageStr = base64_decode($imageData);
$image = imagecreatefromstring($imageStr);
imagepng($image, $somePath);
This works fine. But I now have a new requirement, which is to later read this image, base64-encode it, and post it to Script A which will in turn write it back to the filesystem, exactly as above. Call this second script, the one that reads the data and posts it back to Script A, "Script B". It's when Script A attempts to call imagepng on the data received from Script B that I'm getting my error:
imagepng(): supplied argument is not a valid Image resource
Still with me? Impressive. So what this all means to me is that there is something wrong with the way Script B is reading the .png data from the filesystem, encoding it, and posting it to Script A. It does so as follows (w/o error handling here in the interest of brevity, but no errors are occuring) --
// Read in image file, base64-encode
$fd = fopen($somePath, 'rb');
$size = filesize($somePath);
$data = fread($fd, $size);
fclose($fd);
$encoded = base64_encode($data);
It then posts to Script A using cURL, w/ "$encoded" as a param.
Now, I've found countless examples of this methodology on the 'Net. I'm pretty sure it should work. It doesn't. I've also tried using file_get_contents. Also tried using 'imagecreatefrompng' to read the image, then using output buffer control to capture the image as a stream and base64-encoding that...no luck. In the end I think the approach above is the simplest and most common.
Apologies if this post is too long and/or too hard to follow. Lots of moving parts is all. Any feedback would be greatly appreciated.
Cheers
UPDATE: per Jon Skeet's excellent suggestion to examine the image string as I step through the code using MD5, I've narrowed down the problem - once I write the image to the filesystem in Script B, then read it back in, it has changed. So:
$imageStr = base64_decode($imageData);
$image = imagecreatefromstring($imageStr);
imagepng($image, $somePath);
...seems to manipulate the data, because when I read it back in w/ plain old fread(), the MD5 signature has changed. I think it's the imagepng function, perhaps it adds metadata? The php docs aren't clear about this. If this is the case, I think instead of reading the image back in w/ fread(), I would need to do the opposite of what I'm doing when I write it, something like:
$image = imagecreatefrompng($somePath);
...then figure out a way to get the image's content directly. I can't figure out how to do so though: it seems to require a function like "imagepng($image)", w/o a path, to output the image's content...and that's what I don't want to do.
At this point I think the question is either:
- how can i undo (or reverse) what imagepng seems to do, or
- how can i output an image resource's contents directly
I hope that updating my original post is kosher, I wasn't sure the best way to add further information gleaned.
Thanks