CakePHP: getting image from mysql BLOB To iOS - php

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.

Related

Saving base64 image to server not working in PHP

Iam getting base64 image in a json like below format
{
"profilepic":"iVBORw0KGgoAAAANSUhEUgAAAPAAAABGCAYAAADyxhn6AAAMYml..."
}
I have a PHP code like below, where i decode this base64 image and save it in server, i tried to run the code and am not able to see the image in particular folder location.
Can anyone help me to identify the problem here?
<?php
header("Access-Control-Allow-Origin: *");
$str_json = file_get_contents('php://input'); //($_POST doesn't work here)
$response = json_decode($str_json, true); // decoding received JSON to array
$photo = $response["profilepic"];
// Obtain the original content (usually binary data)
$bin = base64_decode($photo);
// Load GD resource from binary data
$im = imageCreateFromString($bin);
// Make sure that the GD library was able to load the image
// This is important, because you should not miss corrupted or unsupported images
if (!$im) {
die('Base64 value is not a valid image');
}
// Specify the location where you want to save the image
$img_file = 'test/'.uniqid().'.jpg';
// Save the GD resource as PNG in the best possible quality (no compression)
// This will strip any metadata or invalid contents (including, the PHP backdoor)
// To block any possible exploits, consider increasing the compression level
imagejpeg($im, $img_file, 80);
$imgPath = 'http://serverip/'.$img_file;
?>
Please help me to identify the issue

Should a PHP endpoint return an image using 'readfile' or 'base64_encode'?

I'm working on an endpoint that returns a single image from the filesystem (like a user portrait). I use an ajax script for testing that processes the result of an endpoint and sticks it in a div. This raised the issue of constructing an image from an ajax response blob. The solutions I found on SO all assume that the image is being returned in base64 encoding. I got it working by changing the endpoint to output the image with base64 encoding, but this seems like an extra step, especially for iOS clients, which can understand the image being output by readfile.
Is this what people do in production environments? Doesn't conversion to base64 increase the size and put a load on the server? What advantages/disadvantages are there to each method? Is there another way that is even better?
header("Content-type: {$imginfo['mime']}");
// Output the file stream
readfile($filename);
// Output as base64
$type = pathinfo($filename, PATHINFO_EXTENSION);
$data = file_get_contents($filename);
base64_encode($data);
echo base64_encode($data);

Image to base64 encoding issue - 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()

howto determine image type

I have an image from a blob database field.
is there any way to check the mime type of a field without saving?
getimagesize() and mime_content_type()
requires filename...
i want to do something like this:
<img \n" . 'src="data:image/gif;base64,' . $base64 .
'" alt="base64 img" width="80" height="15" />
When you insert file data into your database, you really should be saving the MIME type with it. Detection isn't perfect, and is at least slower.
In any case:
$mime_type = finfo_buffer($f, $imgdata, FILEINFO_MIME_TYPE);
From: Detecting image type from base64 string in PHP
You can inspect the first few bytes in a binary file to determine this. This is called inspecting the "file signature".
Here are some helpful links that I used to write my own code that does this:
bitmap images - Ruby on Rails: How do you check if a file is an image?
GIF and JPG images - http://www.garykessler.net/library/file_sigs.html
PNG images - http://www.w3.org/TR/PNG/#5PNG-file-signature
As far as I'm aware of you cannot do this. It is actually the reason you should always store the image type in the database together with the blob image data.
But basically you can just print the blob data and set your header to show the image in your browser.
header ("Content-type: image/jpeg");
$sql = "SELECT blobfield FROM table WHERE ...";
$result = mysql_query($sql, $conn);
$img = mysql_fetch_row($result);
print $img[0];
It's possible, but you would have to know something about the image types you may encounter. For example, GIF says 'GIF' in the first three bytes of the data.
http://www.onicos.com/staff/iz/formats/gif.html
Using this information you could check the stream from the blob and act accordingly. Not sure if you care about that much work, but it's doable.

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