I encoded a canvas-image to base64 which gives me this:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAICAgICAQICAgICAgIDAwYEAwMDAwcFBQQGCAcICAgHCAgJCg0LCQkMCggICw8LDA0ODg4OCQsQEQ8OEQ0ODg7/2wBDAQICAgMDAwYEBAYOCQgJDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg7/wAARCAAKAAoDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5a/Z7/Zw8EfF/9mT4h6Z4u0GTwt8WNP1iSya7vZp0uNKYJBsItyANjt5o2uGkDBsHhMfDsOn2zWcTQ39tJCUBR5HVGYY4JUEgH2BIHrXunw71vWdI/aa+POraTq+p6Xqr+H/Edy15aXTxTNMt4m2QupDbxubDZyMn1r4yRE8pflXoO1fleQYDEzzHGxnXbjeEop6qPNFtpXb00Wm3zP1vNM2pUMLh5RpK75k3fV8rVm7LzP/Z
which seems like a valid base64-image (decoded it with an online-decoder).
I send this with other (form-) variables with jquery ajax like this:
$.ajax({
type: "POST",
url: "index.php?action=saveNewPost",
data: {text: text, img: encodeURIComponent(base64img)},
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
success: function(){
//...
}
});
on the server this goes to this line:
saveImage(utf8_decode($_POST['img']));
which calls:
function saveImage($base64img){
define('UPLOAD_DIR', '../uploads/');
$base64img = str_replace('data:image/jpeg;base64,', '', $base64img);
$data = base64_decode($base64img);
$file = UPLOAD_DIR . uniqid() . '.jpg';
file_put_contents($file, $data);
}
However, the file isn't saved. What could be wrong?
Lets try to create file test.php in same folder with single function and call, check output errors in browser or /var/log/httpd/error_log
<?php
function saveImage($base64img){
define('UPLOAD_DIR', '../uploads/');
$base64img = str_replace('data:image/jpeg;base64,', '', $base64img);
$data = base64_decode($base64img);
$file = UPLOAD_DIR . '123123123.jpg';
file_put_contents($file, $data);
}
saveImage('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAICAgICAQICAgICAgIDAwYEAwMDAwcFBQQGCAcICAgHCAgJCg0LCQkMCggICw8LDA0ODg4OCQsQEQ8OEQ0ODg7/2wBDAQICAgMDAwYEBAYOCQgJDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg7/wAARCAAKAAoDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5a/Z7/Zw8EfF/9mT4h6Z4u0GTwt8WNP1iSya7vZp0uNKYJBsItyANjt5o2uGkDBsHhMfDsOn2zWcTQ39tJCUBR5HVGYY4JUEgH2BIHrXunw71vWdI/aa+POraTq+p6Xqr+H/Edy15aXTxTNMt4m2QupDbxubDZyMn1r4yRE8pflXoO1fleQYDEzzHGxnXbjeEop6qPNFtpXb00Wm3zP1vNM2pUMLh5RpK75k3fV8rVm7LzP/Z');
That mean that troubles in part AJAX => php script. Now, we try to compare what we recieve from ajax and original string, just change your function to this and look at test.txt:
function saveImage($base64img){
define('UPLOAD_DIR', '../uploads/');
$file = UPLOAD_DIR . 'test.txt';
file_put_contents($file, 'ORIG:'.'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAICAgICAQICAgICAgIDAwYEAwMDAwcFBQQGCAcICAgHCAgJCg0LCQkMCggICw8LDA0ODg4OCQsQEQ8OEQ0ODg7/2wBDAQICAgMDAwYEBAYOCQgJDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg7/wAARCAAKAAoDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5a/Z7/Zw8EfF/9mT4h6Z4u0GTwt8WNP1iSya7vZp0uNKYJBsItyANjt5o2uGkDBsHhMfDsOn2zWcTQ39tJCUBR5HVGYY4JUEgH2BIHrXunw71vWdI/aa+POraTq+p6Xqr+H/Edy15aXTxTNMt4m2QupDbxubDZyMn1r4yRE8pflXoO1fleQYDEzzHGxnXbjeEop6qPNFtpXb00Wm3zP1vNM2pUMLh5RpK75k3fV8rVm7LzP/Z'."\n".'AJAX:'.$base64img);
}
It works - seems when a file is included in php using
include('file.php');
the relative path is from the parent and not from the included file :(
That was the whole problem... Thanks to all
You write encodeURIComponent (JS) and then utf8_decode (PHP). Just use urldecode (PHP) and it will work fine! :)
Related
Trying to save a jpg file to server with the name from an input box but gets saved as Array.jpg
Contents of html file:
<input type="text" name="datepicker" id="datepicker">
Contents of php file:
$image = $_POST['image'];
$location = "upload/";
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$filename = ['datepicker'].'.jpg';
echo $_REQUEST['datepicker'];
$file = $location . $filename;
file_put_contents($file, $image_base64);
Script from the html:
<script type='text/javascript'>
function screenshot(){
html2canvas(document.body).then(function(canvas) {
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
data: {image: base64URL},
success: function(data){
console.log('Upload successfully');
}
});
});
}
</script>
no error messages , just saves with wrong name.
Have now tried:
$filename = ['datepicker']; - saves as: Array (no extension).
$filename = $_POST['datepicker']; (nothing gets saved at all).
$filename = $_POST['datepicker'].'.jpg'; (saves as .jpg (just extension, no file name).
$filename = $_FILES['datepicker']['name']; (nothing gets saved at all).
$filename = $datepicker; (nothing gets saved at all).
$filename = "screenshot_".uniqid().'.jpg'; saved as screenshot_5d40158a1dad5.jpg
It seems to me that the form name field, datepicker, is not available to the php file at all.
Maybe this is because the call (or whatever you call it) to the php file is wrapped in javascript tags? I dont know. Just getting frustrated after 24 hours of trying to get this to work.
I think I have to pass form name field, datepicker, to the ajax code and then use it in the php file.
Anyone know how to amend my code to do this?
I have now resolved this. I had to amend the javascript in the html to include a var with the vale from the text input box and update the ajax to include it in the data line.
<script type='text/javascript'>
function screenshot(){
html2canvas(document.body).then(function(canvas) {
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
var val1 = $('#datepicker').val();
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
//data: {image: base64URL, name: datepicker},
data: {image: base64URL, datepicker: val1},
success: function(data){
console.log('Upload successfully');
}
});
});
}
</script>
Then I had to update the php file with the file name to include the txt data from the form in the filename:
<?php
$image = $_POST['image'];
$location = "upload/";
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$filename = $_POST['datepicker'].'.jpg';
$file = $location . $filename;
file_put_contents($file, $image_base64);
?>
$filename = $_POST['datepicker'].'.jpg';
What you are using is not a good way to store a file in a PHP.
you should prefix current date and some random number generated by PHP to image name before storing the image because if two images are to be stored in the same folder on server's first image will be overwritten and the second file will be stored in its place making the first image to be disappeared completely
try prefixing " date('Ymdhis').rand(100000,999999) " to your image file and use $_FILES['something']['name'] and $_FILES['something']['tmp_name'] to get name and temperary name of the image respectively to store image
I have now resolved this. I had to amend the javascript in the html to include a var with the value from the text input box and update the ajax to include it in the data line.
<script type='text/javascript'>
function screenshot(){
html2canvas(document.body).then(function(canvas) {
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
var val1 = $('#datepicker').val();
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
//data: {image: base64URL, name: datepicker},
data: {image: base64URL, datepicker: val1},
success: function(data){
console.log('Upload successfully');
}
});
});
}
</script>
Then I had to update the php file with the file name to include the txt data from the form in the filename:
<?php
$image = $_POST['image'];
$location = "upload/";
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$filename = $_POST['datepicker'].'.jpg';
$file = $location . $filename;
file_put_contents($file, $image_base64);
?>
I want to upload images to a server using ajax and php.
On client-side i hava the following code:
var reader = new FileReader();
reader.readAsDataURL(file, 'UTF-8');
reader.onload = function (event) {
var result = event.target.result;
$.ajax({
type: "POST",
url: "url",
data: {
data: result,
name: file.name,
mimeType: file.type
}
});
};
On server-side my code looks like the following:
$path = 'somehow/'
$fp = fopen( $path . $_POST['name'], 'w');
$data = explode( ',', $_POST['data'] );
fwrite($fp, base64_decode( $data[ 1 ] ));
fclose($fp);
chmod($path . $_POST['name'], 7777);
list($width, $height) = getimagesize($path . $_POST['name']);
Now the method "getimagesize" always runs into an error "getimagesize(): Read error!"
Does anybody know, why this happens? When i look into the filesystem on the server the file 'FILENAME.JPG' exists ...
You can use $result = #getimagesize($file) to suppress the error.
So, when the $result is empty, means there is an error occurred.
There are two possible reasons for this error : either the url path is incommplete/incorrect or the picture file is corrupt and cannot be opened. A file may be corrupted, for example, if the image is not fully/correctly loaded onto the server.
My problem here is even though it gets saved "successfully" the file is not actually saved. (I'm running this on the Cloud9IDE)
My folder exports is set to be readable and writable via chmod 777 -R ./.
Can someone explain to me why the hello.txt file is not being created, and what I can do to solve this problem?
JQuery:
$("[data-action=save-file]").on("click", function(e) {
var filename = "hello.txt"
var content = "Hello world!"
$.ajax({
type: "GET",
url: "submit.php",
data: {
"filename": filename,
"content": content,
},
cache: false,
success: function(msg) {
console.log(msg)
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log("Some error occurred")
}
})
})
PHP:
<?php
$filename = $_GET["filename"];
$fp = fopen("anon/".$filename, "wb");
if (!$fp) {
echo getcwd();
exit;
} else {
$outputstring = $_GET["outputstring"];
fwrite($fp, $outputstring);
}
$fclose($fp);
?>
I've also tried...
<?php
$filename = $_GET["filename"];
$outputstring = $_GET["outputstring"];
file_put_contents($filename, $outputstring, FILE_APPEND | LOCK_EX);
?>
If this is the actual code that is posted, then the arguments being sent by ajax are "content" and "filename", while php is expecting "outputstring" and "filename", so, on the php end, there is no "outputstring" and the program doesn't check for "content" in $_GET.
$filename = $_GET["filename"];
$outputstring = $_GET["content"];
file_put_contents($filename, $outputstring, FILE_APPEND | LOCK_EX);
Also there is a max length to too url parameters for GET (Max size of URL parameters in _GET), so if file content is ever an actual file this may be truncated. Try using type: "POST" instead.
maybe you should start debugging server side:
first of all, when using file_put_contents, check if it returns false (use operator ===). In this case folder anon/ doesn't exists.
second: check for writability of that folder with is_writable.
if (!isset($_GET[...], $_GET[...])) die("missing vars...");
if (!is_writable($filenamewithpath)) die("dir not writable");
if (file_put_contents(...) === false) die("dir doesn't exists");
if directory not writable, try using chmod($path, 0777). could be that your main directory is 0777 but not the sub-directories.
by the way, as others pointed out, your ajax call is sending "content", not "outputstring" as parameter. you should rename the data object key.
try also to use absolute path (using for example __DIR__ . "/anon/". $filename);
The code in php $fp.close() is error. It should be fclose($fp).
wb is not any mode in php. use w+ instead of wb
and you need to check folder is exist or not
$path = "anon";
if (!file_exists($path) && is_dir($path))
{
if (!mkdir($path, 0777, TRUE))
{
return false;
}
}
My problem is as follows...
I have a screen in which the user can select a PNG image from its computer, using this:
<input id='icon' type='file' accept='image/png' style='width:400px; height:20px' onchange='llenarThumbnail(this)'>
<img id='thumb' src='#'>
When the user selects the image, a thumbnail is shown automatically, using onclick='llenar Thumbnail(this)', like this:
function llenarThumbnail(input){
if (input.files && input.files[0]){
var reader = new FileReader();
reader.onload = function (e){
$('#thumb').attr('src', e.target.result).width(48).height(48);
};
reader.readAsDataURL(input.files[0]);
}
}
Then, when the user clicks on the proper button to upload the image (not a submit button), I do the following to encode the image into Base64:
function getBase64Image(img){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
console.log(dataURL);
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
Then, using AJAX I send this encoded image data to the server, and a PHP script does the following:
$binary=base64_decode($imagen_data);
header('Content-Type: bitmap; charset=utf-8');
$file = fopen($icono, 'wb');
fwrite($file, $binary);
fclose($file);
As I was printing diferent alerts along the process, I could see that the encoding was performing (i'm not so sure if correctly or not), and PHP receives the data and creates the PNG file, but when I open the image, the image is empty, there's no data... Thats why I'm asking if this to methods are compatible... I guess they are because they're both Base64... But if its not this, then what am i doing wrong???
Please, I'm tired of looking for this all over the internet! I need some answers! Thank you!
Without seeing your ajax POST, here's a Wild Guess:
Try leaving the prefix on until the URL gets to php.
Which php server are you using?
Some other usual gotchas:
Make sure you have properly set up your upload directory.
Make sure you have permissions set properly on the upload directory.
Client Side:
// create a dataUrl from the canvas
var dataURL= canvas.toDataURL();
// post the dataUrl to php
$.ajax({
type: "POST",
url: "upload.php",
data: {image: dataURL}
}).done(function( respond ) {
// you will get back the temp file name
// or "Unable to save this image."
console.log(respond);
});
Server File: upload.php
<?php
// make sure the image-data exists and is not empty
// php is particularly sensitive to empty image-data
if ( isset($_POST["image"]) && !empty($_POST["image"]) ) {
// get the dataURL
$dataURL = $_POST["image"];
// the dataURL has a prefix (mimetype+datatype)
// that we don't want, so strip that prefix off
$parts = explode(',', $dataURL);
$data = $parts[1];
// Decode base64 data, resulting in an image
$data = base64_decode($data);
// create a temporary unique file name
$file = UPLOAD_DIR . uniqid() . '.png';
// write the file to the upload directory
$success = file_put_contents($file, $data);
// return the temp file name (success)
// or return an error message just to frustrate the user (kidding!)
print $success ? $file : 'Unable to save this image.';
}
I could not get markE solution to work, had to change the data modification :
From :
$parts = explode(',', $dataURL);
$data = $parts[1];
$data=base64_decode($data)
To :
$img = str_replace('data:image/png;base64,', '', $dataURL);
$img = str_replace(' ', '+', $img);
$data=base64_decode($img);
Method from
I would like to post a base64 image file in a php script through Jquery AJAX..
I already Encoded it with Jquery's encodeURIComponent() function, then decode it with rawurldecode() function on php when the data is posted.
The problem is, the Php can't be able to save the proper image to png.
I have compared the posted base64 data and the original data, and they did not match. which led me to the conclusion that perhaps the base64 data is too large to post.
Is my conclusion true? and if it is, is there any other way I can be able to post the base64 data successfully?
If I was wrong, can you please enlighten me?
This is the Jquery Script
var whereSignatureis = $('.signatureView');
// i got the image from a plugin called jSignature, assign it to a variable data.
var data = signPaper.jSignature("getData","image");
// created an image ddata from what the data returned for displaying purposes.
var ddata = new Image();
// the ddata.src is now the png base64 image
ddata.src = "data:" + data[0] + "," + data[1];
// I encoded the image with uricomponent for safe posting.
var theImg = encodeURIComponent(ddata.src);
// and posted the image
$.ajax({
type: "POST",
url: "processes.php",
data: {img: theImg},
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
success: function(r){
whereSignatureis.append(r);
}
});
This is the Php
define('UPLOAD_DIR', '/images');
$img = rawurldecode($post->img);
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . 'signature' . '.png';
$success = file_put_contents($file, $data);
print $success ? "{$post->img}" : 'File not Saved.';
Thanks in advance!
I found that trying to encode to the base64 text prior to sending just caused problems, since the JavaScript URI encoding functions replace all the spaces in the base64 string with plus signs, breaking the image. I would just remove the encodeURIComponent() function entirely and it should work.