Uploading Picture Is Corrupted - javascript

I am trying to allow users to upload a new profile pic by clicking on the old one.
I am using ajax and a file reader to do so
$('#profileImage').click(function(){ $('#image-file').trigger('click'); });
$('#image-file').on('change',function(){
if (this.files && this.files[0]) {
var FR= new FileReader();
FR.readAsDataURL(this.files[0]);
FR.addEventListener("load", function(e) {
document.getElementById("profileImage").src = e.target.result;
imgData = e.target.result;
var formData = {
'name' : localStorage.getItem('email'),
'image' : imgData
};
console.log("image data: " + imgData);
$.ajax({
type : 'POST',
url : '/uploadprofile.php',
data : formData,
dataType: 'text',
encode : true
}).done(function(data) {
console.log(data);
});
});
}
});
The new image is loaded onto the old picture and the console tracks the image data sent through.
The only issue is that the newly updated picture is not visible to the container. It shows an icon of a broken picture.
This is my php file that handles the insertion
$json = json_decode(file_get_contents('php://input'),true);
if ($json == "") {
$name = $_POST['name'];
$image = $_POST['image'];
} else {
$name = $json["name"]; //within square bracket should be same as Utils.imageName & Utils.image
$image = $json["image"];
}
$response = array();
$decodedImage = base64_decode("$image");
//unlink old picture
// unlink($name.".jpg");
$oldName = $name;
$name .= date("D M d Y G:i");
$name = str_replace(' ', '', $name);
$fullPath = "http://www.mywebsite.com/uploads/".$name.".jpg";
$return = file_put_contents("uploads/".$name.".jpg", $decodedImage);
if($return !== false){
$response['email'] = $oldName;
$response['image'] = $image;
$response['success'] = 1;
$response['message'] = "Image Uploaded Successfully";
$sql = "UPDATE Users SET PicLocation = '$fullPath' WHERE Email = '$oldName'";
$result = $conn->query($sql);
}else{
$response['success'] = 0;
$response['message'] = "Image Uploaded Failed";
}
echo json_encode($response);
The value for $response['image'] that gets printed out is correct but it doesn't seem to show the picture. The data is corrupted somehow. Is there something I should do to get the correct data?
Additionally, sometimes I get the error:
jquery.min.js:2 POST http://tanglecollege.com/uploadprofile.php 406 (Not Acceptable)
I don't know what it means and there doesn't seem to be a good explanation.
Also, the file that gets saved to the server is corrupted in some way. I can track the base64 data being passed along from js to php but when it is saved as a file, that file is corrupted and the image can not be read from the filepath.

Related

How to save canvas image to server with JavaScript and PHP?

I'm struggling with saving my canvas image to server using JavaScript and PHP. I've tried multiple examples for both JS and PHP and it always fails. There's conflicting advice on how to send image data to PHP script (base64, blob, FormData) and I'm not sure how best to communicate back to JS. Currently, zero bytes PNG files are being saved to server and I'm not sure why. I'd like to save generated canvas as a PNG on server and execute a command in JS on success. How best to approach it?
JS:
var off_canvas = document.createElement('canvas');
off_canvas.width = 1080;
off_canvas.height= 1080;
var ctx = off_canvas.getContext("2d");
var brick = new Image();
brick.src = '../img/brick-white.jpg';
brick.onload = function(){
var pattern = ctx.createPattern(this, "repeat");
ctx.fillStyle = pattern;
ctx.fill();
};
var base64img = off_canvas.toDataURL("image/jpeg");
fetch("../php/save_image.php", {
method: "POST",
image: base64img
}) .then(response => response.text())
.then(success => console.log(success)) //execute command
.catch(error => console.log(error));
PHP:
<?php
$img = $_POST['image'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/img")) {
mkdir($_SERVER['DOCUMENT_ROOT'] . "/img", 0777, true);
}
$file = $_SERVER['DOCUMENT_ROOT'] . "/img/".time().'.png';
$success = file_put_contents($file, $data);
print $success ? $file.' saved.' : 'Unable to save the file.';
?>
After some fiddling with multiple options on both JS and PHP, this is what finally worked:
JS
var off_canvas = document.createElement('canvas');
off_canvas.width = 1080;
off_canvas.height = 1080;
var off_ctx = off_canvas.getContext("2d");
off_ctx.beginPath();
off_ctx.rect(20, 20, 150, 800);
off_ctx.fillStyle = "red";
off_ctx.fill();
var brick = new Image();
brick.src = "img/brick-white.jpg";
brick.onload = function(){
var pattern = off_ctx.createPattern(brick, "repeat");
off_ctx.fillStyle = pattern;
off_ctx.fillRect(500, 0, 1000, 1000);
// needs delay to fully render to canvas
var timer = window.setTimeout(save_canvas(off_canvas), 500);
};
function save_canvas(c) {
var b64Image = c.toDataURL("image/png");
fetch("../php/save_image_b64.php", {
method: "POST",
mode: "no-cors",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
body: b64Image
}) .then(response => response.text())
.then(success => console.log(success))
.catch(error => console.log(error));
}
PHP
<?php
$img = file_get_contents("php://input"); // $_POST didn't work
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/img")) {
mkdir($_SERVER['DOCUMENT_ROOT'] . "/img", 0777, true);
}
$file = $_SERVER['DOCUMENT_ROOT'] . "/img/".time().'.png';
$success = file_put_contents($file, $data);
print $success ? $file.' saved.' : 'Unable to save the file.';
?>
in your js page add console.log(base64img);
in your browser console, copy object. i use firefox, if you use something else, then from there copy console message.
the message will be data:image/jpeg;base64,/9j/4AAQSk......
in your php page;
$img = "data:image/jpeg;base64,/9j/4AAQSk.....";
echo "<img src='$data' />"; exit;
now you will know the image is coming or not.
if image is not showing you are not implementing the fetch method correctly
if image is showing, see if you are able to create dir/file. that is, apache has permission to create dir/file. if you are able

How to Convert SVG to image (JPEG, PNG, etc.) in the browser and save on server for product preview to checkout

I'm converting svg using html2canvas to save on server side as png product preview before checkout with base64. The svg works fine. It's for a customized item checkout. The problem is after customization and checkout is clicked, the svg image does not save to preview on checkout page before checking out. Reason is i don't what to write to for the php to save it. I need help in writing the php code for "savetoserver.php" to save to server
function imagetopng(){
function showCheckout() {
$("#checkoutcontainer").show();
$(".productoverview").show();
$("#popup").show();
}
setTimeout(showCheckout, 500);
html2canvas($(".stole"), {
allowTaint: true,
letterRendering: true,
onrendered: function(canvas) {
$('.stole-png').prepend(canvas);
var dataURL = canvas.toDataURL('image/png', 1.0);
$.ajax({
type: "POST",
url: "savetoserver.php",
data: {
imgBase64: dataURL
}
})
.done(function(o) {
var fileurl = o;
var websiteurl = "http://woven.indexsta.com/";
var formatted = websiteurl + fileurl;
//var formatted = "stole-designs/" + fileurl
$('#stole-url').attr('value', formatted);
$('#stolepreview').attr('src', fileurl);
// If you want the file to be visible in the browser
// - please modify the callback in javascript. All you
// need is to return the url to the file, you just saved
// and than put the image in your browser.
});
}
});
$('.stole-png').empty();
};
$('#closecheckout').on('click touch',function(){
$("#checkoutcontainer").css('display','none');
$("#popup").css('display','none');
});
I figured it out. Incase anyone faces same challenge, here's the script i wrote to solve it.
<?php
// requires php5+
// create directory
if (!file_exists('images/')) {
mkdir('images/', 0777, true);
}
define('UPLOAD_DIR', 'images/');
$img = $_POST['imgBase64'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>

Input Image File in VueJs + SlimPHP

I am new in VueJs, I want to input image file and some text using vuejs for creating new user. So far, I already make the base64 image, but I don't know how to pass this base64 image to the slim code in the server.
Here is my vue code:
Input File
<input class="file-input" type="file" name="userPhoto" #change="uploadPhoto">
Method :
uploadPhoto: function(e){
var reader = new FileReader()
reader.readAsDataURL(e.target.files[0])
reader.onload = (e) => {
this.usr.user_photo = e.target.result
}
}
Post :
console.log(this.usr);
this.$http.post('MyAPI', this.usr)
.then(function(response){
this.$router.push({path: '/'});
}
console.log output this object :
Image
and here is my code in slim post request
$app->post('/api/user/add', function(Request $request, Response $response){
//Upload Files
$directory = $this->get('upload_directory');
$uploadFiles = $request->getUploadedFiles();
$uploadedFile = $uploadFiles['userPhoto'];
if($uploadedFile->getError() === UPLOAD_ERR_OK){
$filename = moveUploadedFile($directory,$uploadedFile);
$response->write('Uploaded '.$filename.'<br/>');
}
function moveUploadedFile($directory, UploadedFile $uploadedFile){
$extension = pathinfo($uploadedFile->getClientFilename());
$basename = bin2hex(random_bytes(8));
$filename = sprinf('%s.%0.8s',$basename, $extension);
$uploadedFile->moveTo($directory.'/'.$filename);
return $filename;
}
$user_id = $request->getParam('user_id');
$password = $request->getParam('password');
$name = $request->getParam('name');
$status = $request->getParam('status');
$prodi = $request->getParam('prodi');
$social_link = $request->getParam('social_link');
$sql = "INSERT INTO user
VALUES (:user_id,:password,:name,:status,:prodi,CURRENT_TIMESTAMP(),'$filename',:social_link)";
try{
// Get DB Object
$db = new db();
// Connect
$db = $db->connect();
$stmt = $db->prepare($sql);
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':password', $password);
$stmt->bindParam(':name', $name);
$stmt->bindParam(':status', $status);
$stmt->bindParam(':prodi', $prodi);
$stmt->bindParam(':social_link', $social_link);
$stmt->execute();
echo '{"notice" : {"text": "User Added"}}';
} catch(PDOException $e){
echo '{"Error": {"text": }'.$e->getMessage().'}';
}
});
I already try using resteasy and copy paste all object inside the "usr", but i got this error :
500 Internal Server Error
Can someone tell me how to do this? thanks
Your ajax request contains the image data within a json encoded attribute "user_photo" in form of a Data URI scheme.
This is not a "classic" file upload, so this code won't work like expected.
$uploadFiles = $request->getUploadedFiles();
Instead you may try to read the data URI from the json data.
$userPhoto = $request->getParam('user_photo');
Then try to decode the data URI string and save it as file.
$userPhoto = str_replace("\n", "", $userPhoto);
$userPhotoData = substr($userPhoto, strpos($userPhoto, ',') + 1);
// Decode the base64 string
$userPhotoData = base64_decode($userPhotoData);
// Save the file
file_put_contents('filename.jpg', $userPhotoData);
Notice: Never use echo in Slim. Use the response object instead.
$result = [
'notice' => [
'text' => 'User Added'
]
];
return $response->withJson($result);

File doesn't always upload to server using PHP & Javascript

I have a page that I use to have users press a submit button to insert MYSQL data but also capture an image and upload a .png file to a directory all from the click of one submit button. 9/10 this works perfectly. I'm not sure if it's a connectivity issue (it's being done on a wireless device) or if it's my code. That 1/10 times it will INSERT the MYSQL data but it will not upload the image to the server. Below is my upload code from my file and the upload_data.php file that the code calls. Sorry my formatting on this site isn't the greatest.
<script>
function uploadEx() {
var canvas = document.getElementById("canvasSignature");
var dataURL = canvas.toDataURL("image/png");
document.getElementById('hidden_data').value = dataURL;
var fd = new FormData(document.forms["form"]);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/inc/img/inspection/upload_data.php', true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
console.log(percentComplete + '% uploaded');
//alert('Succesfully uploaded');
}
};
xhr.onload = function() {
};
xhr.send(fd);
};
</script>
BELOW IS UPLOAD_DATA.PHP
<?php
$upload_dir = "upload/";
$img = $_POST['hidden_data'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$id = $_POST['sub_id'];
$file = $upload_dir . $id . ".png";
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
Based on your comment, you are not cancelling the default submit event and that would cause the form to be submitted. And that could cause the ajax request to not finish always.
If you use inline javascript like you do (I would try to move all inline js to the script itself...), you need to make sure that you use something like:
onsubmit="return uploadEx();"
and
onclick="return uploadEx();"
And in your uploadEx() function you end with:
function uploadEx() {
// your code
return false;
}

How do I grab an image on a server and display on a html page?

I am trying to get a canvas that I have saved to pop up in my html window. Not sure how to grab it on the html page because the save generates a random name for the image.
The Save code:
function saveImage() {
cursor.visible = false; stage.update();
var canvasData = testCanvas.toDataURL("image/png");
window.open(("../popup.html"));
var xmlHttpReq = false;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
cursor.visible = true; stage.update();
}
else if (window.ActiveXObject) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
alert (nameOfFile);
ajax.open('POST', 'testSave.php', false);
ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajax.onreadystatechange = function() {
console.log(ajax.responseText);
}
ajax.send("imgData="+canvasData);
}
The PHP:
<?php
// requires php5
define('UPLOAD_DIR', 'images/');
$img = $_POST['img'];
$img = str_replace('data:images/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
The popup.html
<div><strong>Image to display below</strong></div>
<script>
window.onload = function() {
document.getElementById('imgData="+canvasData').src = localStorage.getItem('images/');
};
</script>
Your PHP is already returning the $file that was created on the server.
So, you could POST with jQuery and add a callback that receives that unique filename created on the server (or the error message if an error occurred).
// 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);
});

Categories

Resources