Image to base64 encoding issue - PHP - php

<?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()

Related

php imagick won't save PNG compressed but shows compressed in browser

I have the following code in PHP to take the screenshot of first page of the PDF.
$name = getcwd()."\\testfile";
$img = new imagick();
$img->setResolution(200,200);
$img->readImage($name.'.pdf[0]');
$img->setImageResolution(100,100);
$img->resampleImage(100,100,imagick::FILTER_LANCZOS,1);
$img->setImageCompression(\Imagick::COMPRESSION_ZIP );
$img->setImageCompressionQuality('0');
$img->setImageFormat('png8');
$img->writeImage($name.".png");
header("Content-type : image/png");
echo $img;
This code produces the PNG of 62kb only in the Google Chrome's Resource monitor tab. But the image which is written by Imagick() is above 114kb. Just to make sure image isn't compressed and or any other issues i have used a online service called TinyPNG and they compressed the image shrinking it to exactly 62kb i get in browser...
What could be wrong in this code? Also i am using PNG8 format because thats more efficient.
Best
Ahsan
I think this is caused by your writeImage statement. If you write a PNG image without specifying png8: specifically in the filename your image will not be stored in that format. In essence setImageFormat will only affect when you retrieve the image as a string (echo $img).
If you do the following:
$img->writeImage ('png8:' . $name . ".png");
it should be stored as a png8. You can verify this with identify -verbose and checking the Depth / Channel Depth.
These are the default compression methods used for the following common image formats:
PNG: Imagick::COMPRESSION_ZIP
JPEG: Imagick::COMPRESSION_JPEG
GIF: Imagick::COMPRESSION_LZW

PHP: Show JPG from Binary

I have a jpg blob thats been stored in an external DB and I'm looking to display that as an image via php. The issue is whenever I set the Content-Type to image/jpeg and echo out the blob I get the broken image icon when browsing to it.
I have tried making the file from scratch via sublime and that works when I save it as a hexadecimal file so I know the data is valid.
I have tried making the script create a file but it sets the charset=us-ascii so it won't get seen as a image file.
Does anyone have any experience with raw image binary files? anyone know how I can display the image or even save it out to a file?
Thanks in advance.
P.S. I would provide the binary but its just too big to put on here.
EDIT: (added some code)
<?php
header('Content-Type: image/jpeg;');
$data = 'some long string of hex';
// tried echoing it directly..
echo $data;
// and writing to a file...
file_put_contents('test.jpg', $data);
?>
After continuing research I found this post PHP: create file from an HEX string
With the following code I fixed the issue.
<?php
header('Content-Type: image/jpeg;');
$data = 'The hex data';
$data = pack('H*',$data);
$im = imagecreatefromstring($data);
imagejpeg($im);
?>
Try $im = imagecreatefromstring($data); The output it by imagejpeg($im);

imagepng Very Slow

I have a .php file that's supposed to load an image for display in an img tag(i.e., <img src="the_file.php?which=0"/>). It looks like this:
<?php
ob_clean();
header("Content-type: image/png");
include_once("util.php");
//Do a simple calculation to get $name from (int)$_GET["which"];
$im = imagecreatefrompng("protected_directory/".$name.".png");
imagepng($im,NULL,0,NULL);
imagedestroy($im);
ob_end_flush();
?>
It works correctly, but the image loads substantially slower than just loading it directly(i.e. <img src="protected_directory/the_name.png"/>, where "the_name" was calculated the same way as in the PHP file, but I can't just do this because the protected_directory isn't world readable).
My question is, why is this suddenly so much slower? It's not a large image, but nor is it terribly small.
If you're just displaying an existing file, use readfile() to output it to the browser. There's no need to go through all the overhead of creating an editable GD object for this.
imagepng is known to be slow, if you need to output images with a PHP script, use code like this:
$filename = md5(time() . mk_rand());
imagepng($im, $filename);
echo file_get_contents($filename);
As another answer, I figured out that you can use the third parameter to compress the image (PNG uses zlib). Setting it to 9 works about as well as the other solutions.

Generating PNG images with PHP

I am getting an error when I try to create png files. My code is like:
require_once('....');
header("content-type: image/png");
echo `$command`;
PNG file is generated by $command and the problem is that I include another PHP file and thus it can't display images. How would I be able to solve this?
If you want to show it as an image in the browser, you'll need to base64_encode() it to be sent to the browser instead of just echoing it.
$image = `$command`;
$b64 = base64_encode($image);
echo '<img src="data:image/png;base64,' .$b64. '">';
Or you might try using imagepng() and related GD functions for this.

Sending/Displaying a base64 encoded Image

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).'">';

Categories