PDA

View Full Version : [PHP] Binary JPEG POST; DL as octet: OK. How should you display inline for save?


senocular
01-13-2007, 05:12 PM
I have a post coming into a PHP page that is a JPEG image (raw binary data). Right now I'm reading 'php://input' with fopen and fread and printing the contents using headers of (basically):
'Content-Type: application/octet-stream'
'Content-Disposition: attachment; filename=image.jpg'

This works. The image downloads and you can see it just fine. However, I was trying to get the image to be viewed inline within the browser. I was doing that apparently fine using a header of:
'Content-Type: image/jpeg'

The problem is if you then try to save the image, it doesn't work. What happens is (I think) the page is re-called for the download sans POST data and my "there is no image" error message gets thrown in in place of the JPEG content.

Is there any way to get that to work right (other than a temp file created on the server)?

Thanks

Flash Gordon
01-13-2007, 07:41 PM
how does this look:

//Grab the image
ob_start();
ImageJPEG($img);
$image_buffer = ob_get_contents();
ob_end_clean();
ImageDestroy($img);


//Create temporary file and write to it
$save_as = getcwd() . "/folder_if_you_wish/" . md5( rand() . time() ) . ".jpg";
$fp = fopen("$save_as", 'wb');
fwrite($fp, $image_buffer);
rewind($fp);



Actually this is to save an image on the screen...a quasi screen grab which I don't think you want after all. I think you are saying when the user selected to download the image, the download is corrupt/fails?

senocular
01-13-2007, 07:57 PM
yeah, I don't want to write anything. I have JPEG data (being posted from Flash) into the php page as raw post data. I can immediately throw that into download mode via Content-Disposition: attachment for the user to download to their hard drive just fine (the data successfully saves) or I can post it to the browser window as a jpeg using the Content-Type: image/jpeg header - each of which works as expected. The data is read completely and the file is "sent" to either the user's download location or the browser output, this all without having to save the file anywhere server-side (which is what I'm after, not saving anything on my end)

The problem is that if I go the preview in browser route, a user then trying to save that image after the page has completed results in error - well, not error, but whatever message I have that exists in the case that no post data was read when the page was loaded meaning saving the JPEG from the browser gives you a JPEG image who's content is essentially the text "Error reading file" which means a non-functioning image.

The question is, how would you get that not to happen - to be able to preserve the posted JPEG data for download.

I tried a couple of cache-related headers but they didn't seem to work.

Flash Gordon
01-13-2007, 08:14 PM
Ok....I'm gonna shut up after this last question if I don't have the answer, as clearly you know well more than I ever will...

User actions:

The user sends the image from flash to a php script for previewing in the browser
The user then tries to save the file from flash, (not right-clicking on the image) which sends the image data again to a second php page where the headers is "Content-Disposition: attachment"
This results in an error.
Should the user not preview the image and ask to download, everything works fine.

?

I hate to say it, but the SSL forums here are kind of dead lately with only a handful of people answering. You might was to try your question as phpfreaks.com. They have a very active forum with a lot of great people :o

senocular
01-13-2007, 08:38 PM
Flash already has the image. Flash then opens a browser window separate from its own interface opening the php page Im working on. in opening this window, Flash posts the JPEG data it has to this page - so this is raw JPEG data in RAM now thrown to a standalone php page loading in the browser.

The options in the PHP page are:
Use attachment to force an immediate download of the JPEG data to some place on the user's hard drive
Use image/jpeg to display the JPEG data inline within this new browser window

Ultimately, the destination of this content is on the user's computer. The trick is being able to open the content inline in the browser first without having it saved server-side and then still give the option to save from that page in the browser. It seems, now, the browser can't make that transition on it's own. As soon as that page has completed, the POST data (the image data) is gone and attempting to save it results in a re-execution of the script which is made without the POST data it initially relied on. That is where the "error" occurs (though its not really an error, its just whatever default action I provided given the page being loaded without the posted image content that it expects).

I browsed through phpfreaks already looking at past posts (some were very similar but never got a final answer). I thought Id try here where I know people first ;)

jsebrech
01-14-2007, 01:43 PM
Seems to me there's only two ways you might get this to work:
- trick the browser into fetching the image from cache, which means messing with caching headers
- cache the image server-side (possibly in a php session), and resend it when another request follows. Storing it inside sessions is handy because those get cleaned up by php after a while.

senocular
01-15-2007, 12:40 AM
Seems to me there's only two ways you might get this to work:
- trick the browser into fetching the image from cache, which means messing with caching headers
- cache the image server-side (possibly in a php session), and resend it when another request follows. Storing it inside sessions is handy because those get cleaned up by php after a while.

I was trying to get the first one to work but it doesn't seem to be happening, I think because there is no actual file (?) to cache? Maybe I just did it wrong.

As for sessions, I thought about that too but didn't know how it would work or if it work (haven't tried yet, but that might be the next step). Would the data be lost if the session timed out? I can see someone maybe keeping the image up for a while before wanting to save, and since there is no actual page display for the download, there would be no message indicating that the session data was lost, just a broken, downloaded image.

I have a feeling I might just end up going with the "preview" in Flash and going direct to download from there. I mean, is it necessary to open it up in the browser first? I was thinking for compression's sake, but is that really so important? Meh.

Thanks for the input guys!

jsebrech
01-15-2007, 07:40 AM
Yes, the data would be lost on time-out, but you can configure how long sessions are kept alive, or you can send keepalive requests from the client (if the image is stored in the session, nothing keeps you from serving up a HTML container page first with javascript to poll the server).