I need to send a base64 encoded string to a client. Therefore, I'm opening and reading an image file on the server, encode it and send that data along with the image/jpeg content-type to the browser.
Example in php:
$image = $imagedir . 'example.jpg';
$image_file = fopen($image, 'r');
$image_data = fread($image_file, filesize($image));
header("Content-type: image/jpeg");
echo 'data:image/jpeg;base64,' . base64_encode($image_data);
Clientside, I'm calling:
var img = new Image();
img.src = "http://www.myserver.com/generate.php";
img.onerror = function(){alert('error');}
$(img).appendTo(document.body);
That does not work for some reason. onerror always fires. Watching the FireBug Network task for instance, tells me that I'm receiving the correct header information and a correct value of transfered bytes.
If I send that data as Content-type: text/plain it works, the base64 string is shown in the browser (if I call the script directly). Copying and pasting that output into the src of a <img> element shows the image as expected.
What am I doing wrong here?
Solution
Thanks Pekka for pointing me on my mistake. You don't need (you can't!) encode that binary image data as base64 string in that kind of approach. Without base64 encoding, it just works.
If you set content-type to image/jpeg, you should give just the jpeg data, without the base64 crap. But you're treating the result as if it was html.
You're effectively building a data uri, which is ok, but as you noted, only as an uri. So leave the content type as it is (text/html), and
echo '<img src="data:image/jpeg;base64,'.base64_encode($image_data).'">';
and you're good to go.
I believe it can be done quite efficiently just using php only ... you can use the below function to render images in base64 encoded data
function binaryImages($imgSrc,$width = null,$height = null){
$img_src = $imgSrc;
$imgbinary = fread(fopen($img_src, "r"), filesize($img_src));
$img_str = base64_encode($imgbinary);
if(isset($height) && isset($width))
{
echo '<img src="data:image/jpg;base64,'.$img_str.'" height="'.$height.'" width="'.$width.'"/>';
}
else
{
echo '<img src="data:image/jpg;base64,'.$img_str.'"/>';
}
}
how to use this function
binaryImages("../images/end.jpg",100,100);
run the function binaryImages .. 1st parameter is the image path , 2nd is the width and then the height ... height and width are optional
In this case, there is no reason to base64 encode the image data in the first place. What you want to emit is plain old image data.
Just pass through the JPEG image as-is.
The only way this would make sense to me is if you grabbed the output of generate.php via an AJAX call, and put the result into the src property directly. That should work (although not in IE < 8, but I'm sure you know that). But if you can call generate.php directly as the image's source, I don't see the need for this.
i would recommend it:
base64_encode Encodes data with MIME base64
echo '<img src="data:image/jpeg;base64,'.base64_encode($image).'">';
Related
<?php
header("Content-type: image/jpeg;charset=utf-8'");
$path = 'example/source.jpg';
$da = file_get_contents($path);
$base64 = base64_encode($da);
$src = 'data:image/jpeg;charset=utf-8;base64,'.$base64;
echo '<img src="'.$src.'">';
?>
php v5.6.2
I tired copying the $src value in debug and pasted in img src value. still its not showing up.
what did i missed here?.
thanks in advance
header("Content-type: image/jpeg;charset=utf-8");
here you say to the browser i will send you an jpeg image,
then:
echo '<img src="'.$src.'">';
here you send HTML.
because you said it was a jpeg image, the browser will try to render your html as jpeg. since the ascii text-based HTML format is completely incompatible with the binary based jpeg-format, the browser will fail horribly when trying to render your image, and fail with some error (probably image is corrupt or something like that.)
you can either fix your Content-Type header to specify that you're sending HTML, then the browser will (probably successfully!) try to render it as such, eg:
header("Content-type: text/html;charset=utf-8");
or you can modify your code to actually send the image as jpeg, eg:
<?php
header("Content-type: image/jpeg");
$path = 'example/source.jpg';
readfile($path);
(btw a base64 encoded jpeg image will be about 33% larger than just the raw jpeg image, so if you want a fast pageload, or you want to save up on bandwidth, or you want to save up on ram, using readfile() is faster, requires less bandwidth, and requires less ram, both for the server and the client, compared to your embedded base64 approach.)
So maybe your problem is in your mime type. then try this code two solve:
$path = 'domain.com/example/source.jpg';
$content = file_get_contents($path);
$file_info = new \finfo(FILEINFO_MIME_TYPE);
$mime_type = $file_info->buffer(file_get_contents($path));
$base64 = base64_encode($content);
$src = 'data:'.$mime_type.';charset=utf-8;base64,'.$base64;
echo '<img src="'.$src.'">';
Note: its better to use path from full address domain, if you want to use from path use readfile()
(1)
$file = $_GET['file'];
echo '<img src="'.$file.'" />';
(2)
$file = $_GET['file'];
$imginfo = getimagesize($file);
header('Content-type: '.$imginfo['mime']);
echo file_get_contents($file);`
From these 2 code, my image can show in the browser nicely. But what is the differences of them? Which method should I prefer?
The first example you've posted is simply "including" the image file into the DOM.
It would essentially output something like:
<img src="path/to/image.png" />
While the second option actually sets the Content-Type to whatever the mime of the image is. Meaning if it's a png for example, the page that runs that script will actually be served as a whole image.
If it was a png image, it'd return the content type of image/png.
The key difference is output:
Example 1 references from a path whereas example 2 outputs the binary and labels it an image (so HTTP clients can interpret the response correctly).
To the point... example 1 is preferred because it doesn't have to store the file contents in memory.
The first example you've posted is simply:
output:
<img src="image.png" />
The second option actually sets the Content-Type:
It's return the content type of image/png or image/jpg like that.
I prefered go to second example.
i'm trying to get an image from database using the following code
$this->autoRender=false;
$blob = $this->GeneralNews->findById($id,array("image_data"));
$image = imagecreatefromstring($blob["GeneralNews"]["image_data"]);
ob_start(); //You could also just output the $image via header() and bypass this buffer capture.
imagejpeg($image, null, 80);
$data = ob_get_contents();
ob_end_clean();
echo '<img src="data:image/jpg;base64,' . base64_encode($blob["GeneralNews"]["image_data"]) . '" />';
the result can be seen in the next url
http://www.thedarkdimension.com/generalNews/displayImage/1678
but when i try to get this via iOS in
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
the image that i get is empty although there is a data in (imageData)
i can't figure out the problem but it's most probably came from the PHP side .. cause i tried this URL
http://www.johnquarto.com/wp-content/uploads/2008/08/gag.jpg
and it's ok with it.
Having had a very quick look it appears that what is returned from the URL http://www.thedarkdimension.com/generalNews/displayImage/1678 is not an image but a document claiming to be of type "text/html". That document isn't actually valid HTML but just contains a single img tag with the source attribute being the image base64 encoded. That makes sense given your PHP code.
I suspect what imageWithData is looking for however is just the jpeg in all its binary goodness.
Therefore you need to change your PHP to set the MIME type to image/jpeg and to just echo the jpeg data as it is - not base64 encoding required. I haven't looked at PHP in so long I don't dare give you example code but hopefully thats enough to get you going.
I'm using an image outside of my docroot and want to display that image inside of a function.
How do I correctly do this?
Here is what I have so far: (Both functions are in the same file)
function page(){
echo'
test<br />
'.output().'
';
}
function output(){
header("Content-Type: image/gif");
readfile( '../../../dirOutsideDocRoot/test.gif' );
}
This currently will output the image but I am not able to see the "test" above it. Is it possible to get the image into the page function using header?
The final content you send to the client can have one content-type only. Either image or text. If you want both in a single page, (when image isn't written to file) you could write the image in base64 in the following way:
data:[<MIME-type>][;charset=<encoding>][;base64],<data>
In your case,
data:image/gif;base64,<base64_encoded_image>
See Data URI scheme
Something like the following will work: (Untested)
$img = fread(fopen($path, "r"), filesize($path));
$base64 = "data:image/gif;base64," . base64_encode($img);
It sounds like what you are trying to do is to display an image and text on the same page. To do that you will have to make a page that has the text and has an img tag pointing to another php page that sends back just the image.
Your Content-Type header tells the browser that the entire page is an image. Although, that won't happen either because php will fail saying that data has already been sent so it can't output a header.
Hope this helps.
EDIT: You could also like Cthulhu said, embed the image with base64 like this:
function output(){
$imgbinary = fread(fopen('../../../dirOutsideDocRoot/test.gif', "r"), filesize($filename));
echo '<img src="data:image/gif;base64,' . base64_encode($imgbinary).'" />';
}
For more info about base_64 encoding in php, see http://php.net/manual/en/function.base64-encode.php.
You should have two php pages:
Page 1:
echo'
test<br /><img src="page2.php"/>';
Page 2:
header("Content-Type: image/gif");
readfile( '../../../dirOutsideDocRoot/test.gif' );
I need to send a GET request to my page pic.php, and I want to get a real picture in return.
For now I implemented this idea like this:
<?php
if ((isset($_GET['pic']))&&(isset($_GET['key']))){
$pic = $_GET['pic'];
$pic=stripslashes($pic);
header('Location: /content/'.$pic);
}
?>
But it's not really what I want - it redirects to image directly. What I want is to keep the same URL, but get a needed file depending on what values were submitted.
What is the best way to do that?
thx.
This example code snippet should do what you ask. I've also included code to only strip slashes if magic quotes is enabled on the server. This will make your code more portable, and compatible with future versions of PHP. I also added use of getimagesize() to detect the MIME type so that you output the proper headers for the image, and do not have to assume it is of a specific type.
<?php
if(isset($_GET['pic']))
{
//Only strip slashes if magic quotes is enabled.
$pic = (get_magic_quotes_gpc()) ? stripslashes($_GET['pic']) : $_GET['pic'];
//Change this to the correct path for your file on the server.
$pic = '/your/path/to/real/image/location/'.$pic;
//This will get info about the image, including the mime type.
//The function is called getimagesize(), which is misleading
//because it does much more than that.
$size = getimagesize($pic);
//Now that you know the mime type, include it in the header.
header('Content-type: '.$size['mime']);
//Read the image and send it directly to the output.
readfile($pic);
}
?>
I can see you doing this in two ways:
1) Return the URL to the image, and print out an image tag:
print '<img src=' . $img_url . ' />';
2) Alternatively, you could just pull the data for the image, and display it. For instance, set the header appropriately, and then just print the image data.
header("content-type: image/png");
print $img_data;
This assumes that you have the image data stored in a string $img_data. This method will also prevent you from displaying other things on the page. You can only display the image.
You can load the image, send the image headers, and display the image as such:
header('Content-Type: image/jpeg');
readfile('/path/to/content/pic.jpg');
Obviously the headers would depend on the filetype, but that's easy to make dynamic.
Not sure if I understand what you're after, but guessing that you want to load the picture in an img tag?
If I'm right you just do:
<img src=http://www.domain.com/pic.php?"<?php echo image here ?>" />
Basically you just make the source of the image the webpage you get directed to where the image is.