I am building a hybrid mobile app with cordova and is using the cordova camera plugin. I was able to get the blob:url for the image but hits a dead-end with uploading it to my back-end php server.
Background information:
I have two buttons that I have created to test the cordova camera api.
1 - Take Photo Btn -> Generates a blob url
2 - Upload Photo -> Suppose to upload the image captured based on the photo take to my server via ajax.
Based on my console, I am getting index:file not found and it generates a 0KB image file on my server. I am fairly new to ajax and blob so would appreciate any assistance rendered.
//JS CODE
uploadimgtoserver : function () {
//x is the blobimage url blob:http://localhost:8000/cb420014-a0b9-481a-b3ea-
6657f7e7c98e
var x = localStorage.getItem('data');
$.ajax({
url: 'URL',
type: 'POST',
data: {'file':x},
success: function (data) {
console.log(data);
},
});
}
};
//php code
$data = $_POST['file'];
$data = str_replace('data:image/jpeg;base64,', '', $data);
$data = str_replace(' ', '+', $data);
$data = base64_decode($data);
$file = uniqid() . '.jpg';
$success = file_put_contents($file, $data);
Related
I have a problem generating a pdf with the TCPDF library, and tried to follow some examples that are here, but I have not managed to solve my problem, which is this: when I click on a button I am making an AJAX request Which sends a parameter and the url points to a controller in php with CODEIGNITER, the parameter is used to execute my query and generate the report based on it. I have already debugged the report with static parameters to see if it worked and without using AJAX, and everything went well. The problem is that I need to send the data this way and I do not know how to load the pdf file created in the response of my request, any ideas?
$("#BtnDownload").click(function (){
var jsonString = 2; //Example parameters;
$.ajax({
type: 'POST',
url: baseurl+"reports/selectReport",
data: {'data': jsonString},
success: function(response){
//What my driver should return
}
});
});
This is the function in my controller that I point my ajax request, I do not put all the code of the layout of my report because it is working, and the code is very long, the important thing is to know how to return my generated report And can view it from the browser.
public function selectReport(){
$this->load->library('Pdf');
$pdf = new Pdf('L', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetTitle('report');
$pdf->SetSubject('Report PDF');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->setPrintHeader(false);
$pdf->setFooterData($tc = array(0, 64, 0), $lc = array(0, 64, 128));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->SetFont('dejavusans', '', 12, '', true);
$base_url = base_url();
$data = $this->input->post("data");
// report body
$name_pdf = utf8_decode("report.pdf");
$pdf->Output($name_pdf, 'I');
}
In TCPDF ( according to TCPDF Save file to folder? ) the PDF can be saved:
$dir = 'pdfs/';
$filename = 'report' . microtime(TRUE) . '.pdf';
if( ! is_dir( FCPATH . $dir ) )
mkdir( FCPATH . $dir, 0777, TRUE );
$pdf->Output( FCPATH . $dir . $filename, 'F'); // F saves to filesystem
Since you know the PDFs are in the pdf directory:
$this->load->helper('url');
echo json_encode(array(
'path' => FCPATH . $dir . $filename,
'url' => base_url( $dir . $filename )
));
Then in your ajax success function data.url is the URL to the file:
success: function(response){
if( response.url ){
window.location = response.url;
}
}
Make sure your $.ajax has the configuration for dataType: 'json'.
$.ajax({
// ...
dataType: 'json'
// ...
});
I have integrated summernote in my website (built with Codeigniter) and for texts it is working fine. But for image upload, there arises the following problem.
Summernote reads the image as base64. Now this works perfectly fine for small images, but once images are large, the image finally does not render due to the huge string created by the base64 in the database.
So I am trying to save the image in my server and then use the link of that image.
Following are the codes:
Script for summernote:
<script type="text/javascript">
$(document).ready(function() {
$('#summernote').summernote({
height: 300,
onImageUpload: function(files) {
sendFile(files[0]);
}
});
function sendFile(file) {
data = new FormData();
data.append("files", file);
upload_url = "<?php echo base_url(); ?>" + "general/upload_image";
$.ajax({
data: data,
type: "POST",
url: upload_url,
cache: false,
contentType: false,
processData: false,
success: function(url) {
$(this).summernote("insertImage", url);
}
});
}
});
the php upload_image function:
public function upload_image()
{
if ($_FILES['file']['name']) {
if (!$_FILES['file']['error']) {
$name = md5(rand(100, 200));
$ext = explode('.', $_FILES['file']['name']);
$filename = $name . '.' . $ext[1];
$destination = 'http://sitename.com/dist/img/blogimg/' . $filename; //change this directory
$location = $_FILES["file"]["tmp_name"];
move_uploaded_file($location, $destination);
echo 'http://sitename.com/dist/img/blogimg/' . $filename;//change this URL
}
else
{
echo $message = 'Ooops! Your upload triggered the following error: '.$_FILES['file']['error'];
}
}
}
now, when I click on insert image in summernote or drag and drop an image multiple instances of the following error is shown in the console:
>Uncaught TypeError: Cannot read property 'nodeType' of undefined
This is what I want to achieve,
N.B. This editor is for a blog.
1. User clicks on insert image and uploads an image from his computer.
2. the image is shown in the editor (but not uploaded to server at this step).
3. When user clicks on submit button, then the image should be saved as an image file in a predefined folder.
4. When the page renders the it should have
<img src="mysite.com/path_to_image">
now it is something like
<img src="data:image/jpeg;base64,/9j/4AAQSkZJR....">)
Please note, I tried using onImageUpload within callbacks but the result was nothing was actually happening, neither the image was geting uploaded to the editor nor to the folder in the server.
Where am I going wrong....?? Please help me fix this...
if your summernote version after 0.7
following this
$('#summernote').summernote({
height: 400,
callbacks: {
onImageUpload: function(files, editor, welEditable) {
sendFile(files[0]);
}
}});
Okay, although I could not find a solution to my problem, I have implemented an alternation solution and it works perfectly, although pt. 3 is not catered to and the image is uploaded to the server in an earlier step. That too can be catered with some js scripts...Will do that later... What I did is I targeted the summernote ids and classes and added my codes in place of theirs...
I removed their upload image field by this code:
<style>
/*to disable the upload image from computer uncomment this css code.*/
.note-group-select-from-files {
display: none;
}
</style>
Next I inserted my HTML below their insert link field this way:
document.getElementsByClassName('note-group-image-url')[0].insertAdjacentHTML('afterend','<p class="sober"><p>Click here to upoad image</p></i></p>');
Next I handled the image upload through a modal and wrote a custom js script that copied the image url to the field of .note-image-url
Also I had to customise the javascript of the insert image button of summernote with js so that users can directly click on insert image.
You can add this to your store/ update controller.
It will detect images in your editor, convert and save it in your server.
$body = $data['content'];
$doc = new DomDocument;
libxml_use_internal_errors(true);
$doc->loadHTML($body);
$images = $doc->getelementsbytagname('img');
define('UPLOAD_DIR', 'assets/images/announcement_img/');
foreach($images as $k => $img){
$datas = $img->getattribute('src');
if (strpos($datas, 'data:image')!==false){
list($type, $datas) = explode(';', $datas);
list($media, $format) = explode('/', $type);
list(, $datas) = explode(',', $datas);
$datas = str_replace(' ', '+', $datas);
$datas = base64_decode($datas);
$file= UPLOAD_DIR . time().$k.'.'.$format;
$success = file_put_contents($file, $datas);
print $success ? $file : '<br><br>Unable to save the file.<br><br>';
$img->removeattribute('src');
$img->setattribute('src',base_url().$file);
}
}
$body = $doc->savehtml();
$data['content']=$body;
I am using a web labeling tool to generate image from the website, however I want to modify the function so that when I am done with labeling, instead of downloading the image to local, I want it to be uploaded into server. The function is in a javascript file and all the upload associated with JS has to do with submitting forms. There is no form and super globals, how am I supposed to upload a web generated image to server?
here is the code I currently have, it is not in html file, it is in js file.
var file_data = annotator.export();
var formData = dataURItoBlob(file_data);
var fd = new FormData(document);
fd.append("resultImage",formData);
url="upload/";
http.open("POST", url, true);
// headers
http.setRequestHeader("Content-type", "application/x-www-form- urlencoded");
http.setRequestHeader("Content-length", fd.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(fd);
php file
<?php
$upload_dir = "upload/";
$img = $_POST['hidden_data'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = $upload_dir . mktime() . ".png";
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
Really appreciate your help, thank you.
dataURItoBlob(file_data); by the name of the function it looks like that is going to be returning a blob object. blob/file objects when uploaded to a php script are going to be in the $_FILES global, not $_POST. And you would use move_uploaded_file to move it to your desired destination.
Also you seem to be using the wrong index. You are using hidden_data in your php but you set the name to resultImage in your javascript. You would need to use the same name in php as you did in the javascript.
So your php code should look something like
$upload_dir = "upload/";
$img = $_FILES['resultImage'];
if($img["error"] == UPLOAD_ERR_OK){
//should do other sanitation like making sure the file
//that is uploaded is the actual type of file you expect
$path = $upload_dir . mktime() . ".png";
move_uploaded_file($img["tmp_name"], $path);
}
As a side note, when using and FormData object you do not need to set the request headers like Content-Type as they will automatically be set by the api.
I have unsuccessfully been trying to send a Blob file (which is an .OBJ file type) to the server using AJAX. I want to be able to do this without using an input file field. I am making an online avatar creator, so the Blob file to be sent to the server is generated from the character that is initially imported into my Three.js scene. I have been able to send a Blob file that contains a String to the server and save this to a specified folder (which I am aiming to do with the Blob .OBJ file). I have tried converting the Blob to Base64 before sending it in a POST request, but this did not work. The size of the file that I am trying to send is 3MB.
Here is my JavaScript code for creating the Blob file and sending it to my PHP script on the server using AJAX.
//Create OBJ
var exporter = new THREE.OBJExporter();
var result = exporter.parse(child);
//Generate file to send to server
var formData = new FormData();
var characterBlob = new Blob([result], {type: "octet/stream"});
var reader = new FileReader();
reader.readAsDataURL(characterBlob);
reader.onloadend = function() {
formData.append('file', reader.result);
$.ajax({
url: "ExecuteMaya.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: formData, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
processData:false, // To send DOMDocument or non processed data file it is set to false
contentType: false, // The content type used when sending data to the server
}).done(function(data) {
console.log(data);
});
}
Here is my PHP script for handling the sent file.
<?php
$sourcePath = $_FILES['file']['tmp_name']; // Storing source path of the file in a variable
$targetPath = "upload/".$_FILES['file']['name']; // Target path where file is to be stored
move_uploaded_file($sourcePath,$targetPath) ; // Moving Uploaded file
echo "<span id='success'>Image Uploaded Successfully...!!</span><br/>";
echo "<br/><b>File Name:</b> " . $_FILES["file"]["name"] . "<br>";
echo "<b>Type:</b> " . $_FILES["file"]["type"] . "<br>";
echo "<b>Size:</b> " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "<b>Temp file:</b> " . $_FILES["file"]["tmp_name"] . "<br>";
?>
Any help would be much appreciated!
UPDATE 1: The var result = exporter.parse(child); is a String and whenever I print this variable to the console it takes a few minutes to load. Would the size of this String be a possible issue with trying to send it to the server?
UPDATE 2: This gets printed to the console after the PHP script has been executed, which makes me think that either nothing is being sent over to the server or the sent data is not being handled correctly by the PHP script.
Image Uploaded Successfully...!!File Name: Type: Size: 0 kBTemp file:
UPDATE 3: Here is a link to the file that I am trying to send.
http://www.filehosting.org/file/details/578744/CleanFemaleOBJ.obj
You can view this file in TextEdit/NotePad to view the String that I want to send. It is pretty much a text file with the .obj extension to convert it to that format so it can be opened in Maya.
UPDATE 4: I have now altered my JavaScript code so that the Blob is appended to the FormData and not the result of reader.readAsDataURL(characterBlob).
//Create OBJ
var exporter = new THREE.OBJExporter();
var result = exporter.parse(child);
//Generate file to send to server
var formData = new FormData();
var characterBlob = new Blob([result], {type: "octet/stream"});
formData.append('file', result);
$.ajax({
url: "ExecuteMaya.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: formData, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
processData: false, // To send DOMDocument or non processed data file it is set to false
}).done(function(data) {
console.log(data);
});
Using the following code, I was able to upload the .obj file.
I had to increase my maximum upload size for it to work.
You may also think of increasing your maximum execution time as commented below, but I didn't have to.
For simplicity, I put everything in one file called form.php.
form.php
<?php
// good idea to turn on errors during development
error_reporting(E_ALL);
ini_set('display_errors', 1);
// ini_set('max_execution_time', 300);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo "<br/><b>File Name:</b> " . $_FILES["file"]["name"] . "<br>";
echo "<b>Type:</b> " . $_FILES["file"]["type"] . "<br>";
echo "<b>Size:</b> " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "<b>Temp file:</b> " . $_FILES["file"]["tmp_name"] . "<br>";
echo "<b>Error:</b> " . $_FILES["file"]["error"] . "<br>";
$sourcePath = $_FILES['file']['tmp_name']; // Storing source path of the file in a variable
$targetPath = "uploads/" . $_FILES['file']['name']; // Target path where file is to be stored
if (move_uploaded_file($sourcePath, $targetPath)) { // Moving Uploaded file
echo "<span id='success'>Image Uploaded Successfully...!!</span><br/>";
} else {
echo "<span id='success'>Image was not Uploaded</span><br/>";
}
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
<form action="form.php" method="post" enctype="multipart/form-data">
<label>File</label>
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
<div></div>
</body>
<script>
$(function () {
$('form').on('submit', function (e) {
e.preventDefault();
// logic
$.ajax({
url: this.action,
type: this.method,
data: new FormData(this), // important
processData: false, // important
contentType: false, // important
success: function (res) {
$('div').html(res);
}
});
});
});
</script>
</html>
So, first test to see if you can upload the .obj file using the code above.
As you are testing it out, have your browser's developer tool open. Monitor your Network/XHR tab [Chrome, Firefox] to see the request that gets made when you click Upload.
If it works, try using the same logic in your original code.
var formData = new FormData();
formData.append('file', result);
$.ajax({
url: "ExecuteMaya.php",
type: "post",
data: formData, // important
processData: false, // important
contentType: false, // important!
success: function (res) {
console.log(res);
}
});
Again, monitor the request made in your Network/XHR tab and look at what is being sent.
I have problem with saving canvas image in PHP. I get a blank .png file. I search a lot about this problem but cant find anything useful about this. Why does it save a blank image instead of rendering real image?
JavaScript code:
html2canvas([document.getElementById('dadycool')], {
onrendered: function (canvas) {
var data = canvas.toDataURL();
var image = new Image();
image.src = data;
document.getElementById('imagec').appendChild(image);
console.log(data);
$.ajax({
type: "POST",
url: "up.php",
data: {
imgBase64: data
}
}).done(function(o) {
console.log('saved');
});
}
PHP code:
<?php
// requires php5
define('localhost/samp/sample2/uploads', 'images/');
$img = $_POST['imgBase64'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = localhost/samp/sample2/uploads . uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
I suspect you haven't configured your development box to display PHP error messages. You are defining a constant that is not a valid identifier:
define('localhost/samp/sample2/uploads', 'images/');
That means that you cannot use it directly:
$file = localhost/samp/sample2/uploads . uniqid() . '.png';
... should be triggering:
Notice: Use of undefined constant localhost - assumed 'localhost'
Notice: Use of undefined constant samp - assumed 'samp'
Warning: Division by zero
Notice: Use of undefined constant sample2
Warning: Division by zero
Notice: Use of undefined constant uploads - assumed 'uploads'
Warning: Division by zero
... and file will only contain the base file name (e.g. 53676a01cdb59.png) but not path component. You need to use this syntax:
$file = constant('localhost/samp/sample2/uploads') . uniqid() . '.png';
... or, even better, give the constant a sensible name:
define('DIR_UPLOADS', 'images/');
I was having this same issue - it looked like the base64 data was being sent correctly but always failed to generate the image server side. The solution I found was to use the 'FormData' object and a very simple xhr request to post to the server.
var url='/path/to/save.php';
var data=oCanvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, '');
var fd=new FormData();
fd.append('imgdata',data);
var request = new XMLHttpRequest();
request.open('POST', url);
request.send(fd);
I'm 99% sure the problem was caused by the incorrect Content-Type header being sent by the xhr request. Using a basic xhr request combined with FormData forced the xhr request to be sent with the multipart/formdata content type with correctly defined content boundaries.