Base64Decode to file - whats missing? - php

I have in base64 encoded string in a $_POST field $_POST['nimage'] if I echo it directly as the src value in an img tag, i see the image just fine in browser: echo "<img src='".$_POST['nimage']."'>";
Now, I'm obviously missing a step, because when I base64_decode the string and write it to a file locally on the server, an attempt to view the created file in browser states error:
"The image 'xxxx://myserversomewhere.com/images/img1.jpg' cannot be displayed because it contains errors"
My decode and file put are:
$file = base64_decode($_POST['nimage']);
file_put_contents('images/'. $_POST['imgname'], $file);
which results in images/img1.jpg on the local server. What am I doing wrong in the decode here? Although the base64 output doesn't appear to be URLencoded I have tried urldecode() on it first before base64_decode() just for safe measure with same results.
First few lines of the base64 encode is:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAF4AqsDAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD2gJt+XPJPUGv2A/NB2044oAdtY9M8ccCgB6r8+0jtSYDxEW4xz2qQFCnGOPQ0AAQDJIz9KAF8rI6/hQA9Y+SBgjHIqWA5Yxz2xUsBwUdAMdzSAcFGAB0NADgCVK/KB/OgB6BNzc49agse2OgX2BFZvcCRUO7g

The data you're decoding has a data URI header attached:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...
The header is use by the browser to identify the file type and encoding, but isn't part of the encoded data.
Strip the header (data:image/jpeg;base64,) from the data and base64 decode the rest before writing it to a file: you should be good to go.
$b64 = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...';
$dat = explode(',' $b64);
// element 1 of array from explode() contains B64-encoded data
if (($fileData = base64_decode($dat[1])) === false) {
exit('Base64 decoding error.');
}
file_put_contents($someFileName, $fileData);
NB: Check the return value of your call to base64_decode() for false and abort somehow with a message. It will trap any problems with the decoding process (like not removing the header!).

Related

PHP convert encoding with Shift_JIS

I have a text file. It contains "砡" character and its encoding is Shift-JIS.
I using function file_get_contents() in PHP (Laravel) to read this file, then response in json for client.
$file = file_get_contents("/path/to/file/text");
$file = iconv("SJIS", "UTF-8//IGNORE", $file);
return response()->json(['content' => $file]);
However, this charater "砡" doesn't correctly display, it show to "x".
How do I fix it ?
Try "SJIS-win" instead of "SJIS".

PHP base64 encoded image not displaying correctly

I'm trying to send an image (any size) over to an API I'm creating, using base64 encoding. The encoded string hits my API as a parameter in the URL. The API built with PHP.
Once the request hits my API, I want to store the image onto my server, and save the file name in the database. This is working, however I'm getting some odd outputs with the actual image.
For reference, I also followed http://blog.justin.kelly.org.au/simple-base64-encodedecode-url-safe-functions/ but have the same results.
The image I am trying to store on my server:
$encode = base64_encode(file_get_contents($image));
echo $encode;
For testing, the ouput of this is the string I'm using to pass to my API.
In the API:
$image = base64_decode($_POST['image']));
$image_name = md5($image) . ".jpg";
file_put_contents(/public/image/ . $image_name, $image);
This works, my image is put onto the server in the correct directory with a random name which is saved to the database.
However, when navigating to the image directly, the image is warped:
If you have a sharp eye, the top part of the image is actually correct before it starts to fail, which makes me start to think whether the string is not getting encoded correctly to be sent as a parameter?
Any clues would be lovely, cheers.
EDIT: Changed it to POST, removed urlencode/decode & removed strtr.
Thanks to the comments:
base64_encode(file_get_contents($image_path));
No urlencode or strtr needed. Use POST request, and alter the post_max_size on the web server to allow for bigger images to be passed through.
$image = base64_decode($this->getParameters('avatar'));
$image_name = md5($image) . ".jpg";
Maybe I'm looking at it wrong, but first you encode it base64 -> urlencode and then you decode it base64 -> urldecode again, shouldn't the latter be in reverse order?

How to save a base64 decoded image in the filesystem using php?

I am getting a base64 encoded JPEG string via a POST request to my web service.
I want to decode it and save it in the filesystem.
How can I achieve this using PHP 5.3.
I am able to successfully decode the data using the base64_decode function.
How can I save this decoded string as a JPEG image in the server?
Thanks in advance.
If you are sure the image will always be jpg then you can simply use: file_put_contents();
<?php
$decoded=base64_decode($encodedString);
file_put_contents('newImage.JPG',$decoded);
//leave it to you to randomize the filename.
?>
Replacing the blank spaces with + signs is required if the data is derived from canvas.toDataURL() function.
$encodedString = str_replace(' ','+',$encodedString);
See this question
It helped a lot in my case.

base64 encode an image without saving

Can I base64 encode an image that I created on the fly, without first saving it to disk? As far as I know, base64_encode() only accepts strings, and I couldn't find a way to retrive image source object as string without first saving it, and load it with file_get_contents()
GD doesn't provide a method to return an output image as text, but you can fake it with the output buffering functions:
ob_start();
imagejpeg($handle); // no second parameter, will do output instead of writing to file
$img = ob_get_clean();
echo base64_encode($img);

How can I convert a large string of base64 image data back to an image with PHP?

I have a large string of base64 image data (about 200K). When I try to convert that data by outputting the decoded data with the correct header, the script dies, as if there isn't enough memory. I get no error in my Apache logs. The example code I have below works with small images. How can I decode a large image?
<?php
// function to display the image
function display_img($imgcode,$type) {
header('Content-type: image/'.$type);
header('Content-length: '.strlen($imgcode));
echo base64_decode($imgcode);
}
$imgcode = file_get_contents("image.txt");
// show the image directly
display_img($imgcode,'jpg');
?>
Since base64-encoded data is cleanly separated every 4 bytes (i.e. 3 bytes of plaintext are encoded into 4 bytes of base64-encoded text), you could split your b64 string into multiples of 4 bytes, and process them separately:
while (not at end of string) {
take next 4096 bytes // for example - 4096 is 2^12, therefore a multiple of 4
// you could use much larger blocks, depends on your memory limits
base64-decode them
append the decoded result to a file, or a string, or send it to the output
}
If you have a valid base64 string, this will work identically to decoding it all at once.
OK, here is a closer resolution. While this seems to decode the base64 data in smaller chunks, I still don't get an image in the browser. If I echo the data before I place a header, I get output. Again, this works with a small image but not a large one. Thoughts?
<?php
// function to display the image
function display_img($file,$type) {
$src = fopen($file, 'r');
$data = "";
while(!feof($src)) {
$data .= base64_decode(fread($src, 4096));
}
$length = strlen($data);
header('Content-type: image/'.$type);
header('Content-length: '.$length);
echo $data;
}
// show the image directly
display_img('image.txt','jpg');
?>
Content-length must specify the actual (decoded) content length not the length of the base64 encoded data.
Though I'm not sure that fixing it would solve this problem...
Save the base64 string to an image file using imagejpeg() or the correct function for the different formats, and then display the image with a simple <img> tag.

Categories