I've created a functionality on my website where user's can change the background image via upload. The procedure is following:
User goes to settings page and selects an image file to be uploaded. After selecting image, the browser will output it so that user can preview
it before actually saving it's file to in to the folder and filepath in to the database. After that, if user is happy with the result, he can save it to the
folder by pressing "Upload Background Image" button.
All of the above is handled with AJAX.
I am having trouble to just output the image to the browser without actually saving it twice, first into tests folder and after that into backgrounds folder.
I'm using CodeIgniter as my backend framework and jQuery for my AJAX requests.
Here are my methods for outputting (testing) and saving the image:
public function test_image()
{
if($this->input->is_ajax_request())
{
// This part of code needs to be replaced to only just output the image (return it as a JSON), not actually saving it to another a folder
$ext = pathinfo($_FILES['userfile']['name'], PATHINFO_EXTENSION);
$new_img_name = random_string('unique'). "." . $ext;
$config['upload_path'] = './public/images/uploads/tests';
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$config['max_size'] = '1000000';
$config['max_width'] = '2000';
$config['max_height'] = '1600';
$config['file_name'] = $new_img_name;
$this->load->library('upload', $config);
if (!$this->upload->do_upload()) {
$this->output->set_content_type('application_json');
$this->output->set_output(json_encode(array('image_errors' => $this->upload->display_errors('<p class="text-center">','</p>'))));
return false;
} else {
$this->output->set_content_type('application_json');
$this->output->set_output(json_encode(array('userfile' => $new_img_name)));
}
} else {
echo "Not an ajax request";
}
}
// This method works properly
public function upload_background_image()
{
if (isset($_POST))
{
$ext = pathinfo($_FILES['userfile']['name'], PATHINFO_EXTENSION);
$new_img_name = random_string('unique'). "." . $ext;
$config['upload_path'] = './public/images/uploads/backgrounds';
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$config['max_size'] = '1000000';
$config['max_width'] = '2000';
$config['max_height'] = '1600';
$config['file_name'] = $new_img_name;
$this->load->library('upload', $config);
if (!$this->upload->do_upload()) {
$this->output->set_content_type('application_json');
$this->output->set_output(json_encode(array('image_errors' => $this->upload->display_errors('<p class="text-center">','</p>'))));
return false;
} else {
$this->load->model('user_model');
$user_id = $this->session->userdata('user_id');
$upload_photo = $this->user_model->updateUserInfo($user_id, ['body_background_url' => $new_img_name]);
if ($upload_photo === true) {
$this->session->set_userdata(['body_background_url' => $new_img_name]);
redirect(base_url());
}
}
}
}
And here's my AJAX:
$("#bg-cover-file").change(function(e) {
e.preventDefault();
var form = $(this).closest('form');
form.ajaxSubmit({
dataType: 'json',
beforeSubmit: function() {
},
success: function(response) {
if(response.userfile) {
// Output the image
$('.test-image').attr('src', response.userfile);
$('span.file-input').hide();
// Change the form action attribute
var new_path = 'uploads/upload_background_image';
form.attr('action', new_path);
} else {
$('#error-modal').modal('show');
$("#error-body").html(response.image_errors);
return false;
}
}
});
return false;
});
--Working Demo--
I have put comments in this demo to explain what the steps are so please read them.
If you don't understand anything in this answer please leave a comment below and i will update the answer until you understand line for line. You don't learn from copy/paste so please be sure to understand the answer.
function MyFunction() {
var img=document.getElementById('BackgroundImage');
var Status=document.getElementById('Status');
var savebtn=document.getElementById('savebtn');
/* SetBG will target the body tag of the web page.
You can change this to any element -
var SetBG=document.getElementById('YourID').style;
*/
var SetBG=document.body.style;
//Split the image name
var fileExt=img.value.split('.');
//Use the last array from the split and put to lowercase
var fileformat=fileExt[fileExt.length -1].toLowerCase();
// Check the file extension (Image formats only!)
if((fileformat==='jpg')||(fileformat==='gif')||(fileformat==='png')||(fileformat==='jpeg')) {
if (img.files && img.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
//----Image is ready for preview.
SetBG.background='url('+e.target.result+') no-repeat center center fixed';
/*---- Optional, Set background as cover ---*/
SetBG.backgroundSize="cover";
SetBG.OBackgroundSize="cover";
SetBG.webkitBackgroundSize="cover";
//--Hide Loading Message
Status.style.display="none";
//----- Display (Save/Upload button?)
savebtn.style.display="block";
}
/*-------Reading File....
Display a message or loading gif for large images to be processed?
*/
Status.innerHTML="Loading...";
Status.style.display="block";
savebtn.style.display="none";
reader.readAsDataURL(img.files[0]);
}
}else{
/*----User file input not accepted (File isn't jpg/gif/png/jpeg)
Empty the input element and set the background to default.
*/
Status.innerHTML="Format not accepted";
Status.style.display="block";
savebtn.style.display="none";
SetBG.background='white';
document.getElementById('BackgroundImage').value='';
}
}
#Status{display:none;background:white;color:black;font-size:16pt;}
#savebtn{display:none;}
<div id="Status"></div>
<input type="file" id="BackgroundImage" onchange="MyFunction()"/>
<button id="savebtn" onclick="alert('Now upload the image');">Upload and save</button>
I hope this helps. Happy coding!
This may help you
let assume your browse button's id is bg-cover-file and the id of the image tag where you want to display the image preview_image
$(document).on("change", "#bg-cover-file", function(event)
{
if (this.files && this.files[0])
{
var reader = new FileReader();
reader.onload = function (e)
{
$('#preview_image').attr('src', e.target.result);
}
reader.readAsDataURL(this.files[0]);
}
});
function MyFunction() {
var img=document.getElementById('BackgroundImage');
var Status=document.getElementById('Status');
var savebtn=document.getElementById('savebtn');
/* SetBG will target the body tag of the web page.
You can change this to any element -
var SetBG=document.getElementById('YourID').style;
*/
var SetBG=document.body.style;
//Split the image name
var fileExt=img.value.split('.');
//Use the last array from the split and put to lowercase
var fileformat=fileExt[fileExt.length -1].toLowerCase();
// Check the file extension (Image formats only!)
if((fileformat==='jpg')||(fileformat==='gif')||(fileformat==='png')||(fileformat==='jpeg')) {
if (img.files && img.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
//----Image is ready for preview.
SetBG.background='url('+e.target.result+') no-repeat center center fixed';
/*---- Optional, Set background as cover ---*/
SetBG.backgroundSize="cover";
SetBG.OBackgroundSize="cover";
SetBG.webkitBackgroundSize="cover";
//--Hide Loading Message
Status.style.display="none";
//----- Display (Save/Upload button?)
savebtn.style.display="block";
}
/*-------Reading File....
Display a message or loading gif for large images to be processed?
*/
Status.innerHTML="Loading...";
Status.style.display="block";
savebtn.style.display="none";
reader.readAsDataURL(img.files[0]);
}
}else{
/*----User file input not accepted (File isn't jpg/gif/png/jpeg)
Empty the input element and set the background to default.
*/
Status.innerHTML="Format not accepted";
Status.style.display="block";
savebtn.style.display="none";
SetBG.background='white';
document.getElementById('BackgroundImage').value='';
}
}
#Status{display:none;background:white;color:black;font-size:16pt;}
#savebtn{display:none;}
<div id="Status"></div>
<input type="file" id="BackgroundImage" onchange="MyFunction()"/>
<button id="savebtn" onclick="alert('Now upload the image');">Upload and save</button>
Related
I'm using a script which resizes images client side before uploading them via Ajax to a PHP file. I am resizing images client side to reduce the power demand on the server. My script works but is taking too long to upload the image and I need help understanding why this is the case. The first part of the file asynchronously resizes the image. The second part encodes the resized image source to dynamically created hidden input and finally, Ajax uploads the dynamically created input value to a PHP file by using a timeout 3-second delay function.
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
/* Upload Logo Image */
$("#loader-wrapper").hide();
$("#logo_image").change(function(){
$("#ImgText").fadeOut(10, "linear");
$("#loader-wrapper").css('background-image', 'none').fadeIn(200, "linear");
const form = document.querySelector('#user_update_settings');
form.addEventListener('change', async (e) => {
e.preventDefault();
// Get data URI of the selected image
const formData = new FormData(e.currentTarget);
const photoField = formData.get('logo_image');
const dataUri = await dataUriFromFormField(photoField);
// Defines Resized image URL
const imgEl = document.createElement('img');
imgEl.addEventListener('load', () => {
const resizedDataUri = resizeImage(imgEl, 600);
// Deletes Previous Input
var element = document.getElementById('new_logo_image');
if (typeof(element) != 'undefined' && element != null)
{
var elementExists = document.getElementById("new_logo_image");
elementExists.remove();
}
// Creates New Input
var objTo = document.getElementById('LogoInputContainer')
var image_input = document.createElement("input");
image_input.setAttribute("name", "new_logo_image");
image_input.setAttribute("id", "new_logo_image");
image_input.setAttribute("type", "hidden");
image_input.setAttribute("value", resizedDataUri);
objTo.appendChild(image_input);
});
imgEl.src = dataUri;
});
// Resize Script
function dataUriFromFormField (field) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.addEventListener('load', () => {
resolve(reader.result);
});
reader.readAsDataURL(field);
});
}
function resizeImage(imgEl, wantedWidth) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const aspect = imgEl.width / imgEl.height;
canvas.width = wantedWidth;
canvas.height = wantedWidth / aspect;
ctx.drawImage(imgEl, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL();
}
});
// Image Upload
$("#logo_image").change(function(){
setTimeout(() => {
if(window.File && window.FileReader && window.FileList && window.Blob){
if($(this).val()){
// Checks File Extension
var fileExtension = ['jpeg', 'jpg', 'png', 'gif', 'bmp'];
if ($.inArray($(this).val().split('.').pop().toLowerCase(), fileExtension) == -1) {
alert("Only formats are allowed : "+fileExtension.join(', '));
exit();
}
$.ajax({
url: "/logo_uploader",
type: "POST",
data: new FormData($("#user_update_settings")[0]),
contentType: false,
cache: false,
processData: false,
dataType: 'json',
success:function(response){
if(response.type == 'success'){
$("#loader-wrapper").fadeOut();
$(".logo_image_container").css("background-image", "url("+ response.logo_image +")");
}else{
$("#loader-wrapper").fadeOut();
$("#ImgText").fadein(10, "linear").text("+ response.msg +");
}
}
});
}
} else {
alert("Can't upload! Your browser does not support File API!</div>");
return false;
}
}, 3000);
});
});
Client-side, my logo uploader validates the file type, deletes the previous image [if it exists] decodes the $request->new_logo_image and saves the file in the folder 'logos' and in a SQL database.
// User ID
$user_id = auth()->user()->id;
// Reserved Goods
$user = Users::where('id', $user_id)->first();
// Path
$FilePathDB = FilePathDB::first();
// Path
$file_path = $FilePathDB->public_img_path;
$path = $file_path.$user->logo_image;
// Deletes Previous Logo [If Applicable]
if(file_exists($path)) {
File::delete($path);
}
// Validates Extension
$validatedData = $request->validate([
'logo_image' => 'required|image|mimes:jpg,png,jpeg',
]);
// Generates a Unique New Name
$new_name = 'logos/'.$user_id.trim($user->username).uniqid().'.jpg';
// Uploads request Image if file does not exist
if($request->hasFile('logo_image')) {
$image = $request->new_logo_image; // your base64 encoded
$image = str_replace('data:image/png;base64,', '', $image);
$image = str_replace(' ', '+', $image);
File::put($file_path.$new_name, base64_decode($image));
// Logo Image Variable
$formFields = array(
'logo_image' => $new_name
);
// User ID Update
$users = Users::where('id', $user_id)
->update($formFields);
// If Successful
$response = print json_encode(array(
'type'=> 'success',
'msg' => 'Logo Uploaded Successfully',
'logo_image' => 'storage/'.$new_name,
));
} else {
// If unsuccessful
$response = print json_encode(array(
'type'=> 'failed',
'msg' => 'Ooops, image upload unsuccessful. Please try again!',
));
}
Condensed HTML
<form method="POST" action="/user_update_settings" id="user_update_settings" enctype="multipart/form-data">
<label for="logo_image" class="pointer UploadImgBtn transition">
<input class="DisplayNone" type="file" name="logo_image" id="logo_image" accept="image/*">
<a>Upload Image</a>
</label>
</form>
On average, for a 3MB image, it takes 3 seconds for JS canvas to resize the image and 15-20 seconds to upload the already resized file - now between 40-50KB in size. Knowing the image has been resized, why does it take so long for my code to upload the resized image? Are there any loops I haven't considered running in the background which are consuming the client's resources?
After much thinking, I have just found the solution. When I ran my Ajax script I was submitting the whole form to the server which included both the old and the new image. To reduce the data load, one can either put the hidden input into a new form or else specify the data which is to be sent to the PHP file.
I have a database in which there are images stored as LONGBLOB files. It seems I can't figure out how to "transport" those images to JS file so I could check their dimensions and compare them with the dimensions of the screen. Here is how I donwload the images:
function fillArrays(){
$idArray = array();
$sql = "SELECT oglas_id,slika,prioriteta FROM deska WHERE deska.datumz <= CURRENT_DATE AND deska.datumk >= CURRENT_DATE;";
$result = mysqli_query($GLOBALS['conn'],$sql);
$resultCheck = mysqli_num_rows($result);
if($resultCheck>0){
while($row = mysqli_fetch_assoc($result)){
array_push($GLOBALS['idArray'],$row['oglas_id']);
$image = base64_encode($row['slika']); // THIS "slika" means "image" in my lang...
array_push($GLOBALS['imgArray'],$image); //AND THIS
array_push($GLOBALS['prArray'],$row['prioriteta']);
}
}else{
die("Oops there seems to be an error(arr)");
}
}
I am preety sure everything in lines of SQL is correct. The problem begins when I try to get the images stored in array into javascript. I am trying to do it by json_encode.
<script>
var idArray = <?php echo json_encode($idArray) ?>;
var imgArray = <?php echo json_encode($imgArray) ?>;
var prArray = <?php echo json_encode($prArray) ?>;
</script>
<script src="includes/script.js"></script>
Then we jump to my javascript file ( script.js ). Now when I try to output the dimensions of the image selected, it says undefined undefined (width*height).
Here is how I try to obrain the info of the image selected.
in my JS file:
var imgArray = window.imgArray;
var img = new Image();
img = imgArray[0];
img.width;
img.height;
I am aware the questions has been asked many times but I can't seem to wrap my head around it so I figured I would supply you guys with my concrete problem.
Thanks to anyone who helps.
Since I dont think people fully understand:
Aim of the site:
Download images from database.
Resize them.(IMAGE CANNOT BE LARGER THAN HALF OF THE SCREEN SIZE)
Place them in the 2x2 table.
You need to wait for the loaded image.
img.onload = function () {
alert(this.width + ' ' + this.height);
};
Btw, if you need to resize the image, why don't you pass the screen resolution to PHP and then, there, you do all your checks? It's easier, because if you do this from JS, it depends on user browser.
Code for reading image data :
function readURL(input) {
console.log(input.files);
if (input.files && input.files[0]) {
var reader = new FileReader();
//alert(input.files[0]);
reader.onload = function (e) {
$('#image_source').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
Convert the fetched image to base64 :
var handleFileSelect = function(evt) {
var files = evt.target.files;
var file = files[0];
if (files && file) {
var reader = new FileReader();
reader.onload = function(readerEvt) {
var binaryString = readerEvt.target.result;
document.getElementById("hidden_id").value = btoa(binaryString);
};
reader.readAsBinaryString(file);
}
};
Add listener for image input type :
if (window.File && window.FileReader && window.FileList && window.Blob) {
document.getElementById('image_id').addEventListener('change', handleFileSelect, false);
} else {
alert('The File APIs are not fully supported in this browser.');
}
Hope it helps you.
I want the user of my page to :
browse a movie file from his local computer
get an image from the movie he just input it in step 1
name the image file exactly the same with the movie file name
upload to the server this image file
Thanks to the link from codepen here, I can pass step 1 and step 2 above.
(Please have a look to the link above for the complete codes), The HTML :
<p><strong>Select a video or image file</strong><br /><br />Supported browsers (tested): Chrome, Firefox, Safari, Opera, IE10, IE11, Android (Chrome), iOS Safari (10+)</p>
<div></div>
So, I copy/paste the codes to my page. After this I can just go to the next steps "manually" by telling the user to
(3a) right click the image and choose "Save image as..."
(3b) rename the file in the "Save image as" dialog box exactly the
same with the movie file name and put a .jpg extension instead of the
default one which is .png
(3c) from the form I provide, browse his local computer and select
this jpg file
(4) push the "Submit" button to upload the jpg file to the server
Suppose I'm the user, I click the "Browse" button and select SinCity.mp4 movie. Then I saw the page showing a still image from the movie. Without doing 3a, 3b and 3c, I just click another button - which is the "Submit" button to upload SinCity.jpg
My question is : will it be possible to "auto" step 3 so the user doesn't have to do 3a, 3b and 3c ?. I mean the process of 3a 3b 3c are taken over by a script. If possible, would somebody help me for the script ?
FYI, my page is in .php extension file.
Thank you in advanced.
=====================================================================
EDIT : I found the answer.
Thank you to all user who submit a codes in the internet and thank you also to Douwe de Haan who help me on how to do it. I'm sorry since I can not put more than two links in my post, I will just copy/paste the codes which come from 3 different sources, in case there is someone who face the same case with me.
First, the CSS :
div {
line-height: 200px;
}
img {
padding: 5px;
vertical-align: middle;
text-align: center;
}
#supports (object-fit: cover) {
img {
object-fit: cover;
}
}
The css above I got it from anon/pen in codepen.
The HTML :
<input type="file" accept=".jpg,.jpeg.,.gif,.png,.mov,.mp4" onchange="document.getElementById('file').value =
this.value.split('\\').pop().split('/').pop()" />
<p><strong>Select a video or image file</strong><br /><br />Supported browsers (tested): Chrome, Firefox, Safari, Opera, IE10, IE11, Android (Chrome), iOS Safari (10+)</p>
<div></div>
<input type="button" onclick="uploadEx()" value="Upload" />
<form method="post" accept-charset="utf-8" name="form1">
<input name="hidden_data" id='hidden_data' />
<input type="text" name="file" id='file' type="hidden"/>
</form>
The html above is a combination which I got from
anon/pen in codepen
the onchange="document.getElementById('file').value I got it from
shijin/4EnRQ/ in jsfiddle and
the onclick="uploadEx()" I got it from
"upload-html-canvas-data-to-php-server" in codepool.
The SCRIPT :
<script>
document.getElementsByTagName('input')[0].addEventListener('change', function(event) {
var file = event.target.files[0];
var fileReader = new FileReader();
if (file.type.match('image')) {
fileReader.onload = function() {
var img = document.createElement('img');
img.src = fileReader.result;
document.getElementsByTagName('div')[0].appendChild(img);
};
fileReader.readAsDataURL(file);
} else {
fileReader.onload = function() {
var blob = new Blob([fileReader.result], {type: file.type});
var url = URL.createObjectURL(blob);
var video = document.createElement('video');
var timeupdate = function() {
if (snapImage()) {
video.removeEventListener('timeupdate', timeupdate);
video.pause();
}
};
video.addEventListener('loadeddata', function() {
if (snapImage()) {
video.removeEventListener('timeupdate', timeupdate);
}
});
var snapImage = function() {
var canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
var image = canvas.toDataURL();
var success = image.length > 100000;
if (success) {
var img = document.createElement('img');
img.src = image;
document.getElementsByTagName('div')[0].appendChild(img);
URL.revokeObjectURL(url);
}
return success;
};
video.addEventListener('timeupdate', timeupdate);
video.preload = 'metadata';
video.src = url;
// Load video in Safari / IE11
video.muted = true;
video.playsInline = true;
video.play();
};
fileReader.readAsArrayBuffer(file);
}
});
function uploadEx() {
var dataURL = document.images[0].src;
document.getElementById('hidden_data').value = dataURL;
var fd = new FormData(document.forms["form1"]);
var xhr = new XMLHttpRequest();
xhr.open('POST', '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>
The script above I got it from anon in codepen, the last function uploadEX() I got it from "upload-html-canvas-data-to-php-server" in codepool and the document.images[0].src;I got it from W3School.
Finally the upload_data.php
<?php
$upload_dir = "uploads/";
$img = $_POST['hidden_data'];
$file_name = substr($_POST['file'],0,-4);
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = $upload_dir . $file_name . ".jpg";
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
The php above I got it from "upload-html-canvas-data-to-php-server" in codepool.
Thank you very much, All.
If you'll accept that the user doesn't download anything and the flow is changed to this:
User selects a movie
Script gets a still to upload
User presses upload button and still is uploaded
Then yes, it just takes a few steps:
Create a hidden input in the form named something like snapshot_base64
<input type="hidden" name="snapshot_base64" id="snapshot_base64">
Next, in the codepen you provided is a line that says var image = canvas.toDataUrl(). After that line, put the following code:
snapshot_input = document.getElementById('snapshot_base64');
snapshot_input.setAttribute('value', image);
This loads the base64 data into the hidden input.
What you still need to to yourself is grabbing the name of the uploaded movie and add that to a hidden input as well, so you'll know what name to give to the file.
After this you'll need to submit the form and read the base64 in the php files you are using.
Converting base64 to an image is described here.
This is a tangent from the question here:
Returning value to Javascript from PHP called from XMLHttpRequest
I am adding an "image upload" button to my AjaxChat. I am using an XMLHttpRequest to send the image to the server, where I run a PHP script to move it to my images folder. Below is the Javascript function in charge of opening the XMLHttpRequest connection and sending the file:
function uploadImage() {
var form = document.getElementById('fileSelectForm');
var photo = document.getElementById('photo');
var uploadButton = document.getElementById('imageUploadButton');
form.onsubmit = function(event) {
event.preventDefault();
// Update button text
uploadButton.innerHTML = 'Uploading...';
//Get selected files from input
var files = photo.files;
// Create a new FormData object
var formData = new FormData();
// Loop through selected files
for (var i = 0; files.length > i; i++) {
var file = files[i];
// Check file type; only images are allowed
if (!file.type.match('image/*')) {
continue;
}
// Add file to request
formData.append('photo', file, file.name);
}
// Set up request
var xhr = new XMLHttpRequest();
// Open connection
xhr.open('POST', 'sites/all/modules/ajaxchat/upload.php', true);
// Set up handler for when request finishes
xhr.onload = function () {
if (xhr.status === 200) {
//File(s) uploaded
uploadButton.innerHTML = 'Upload';
var result = xhr.responseText;
ajaxChat.insertText('\n\[img\]http:\/\/www.mysite.com\/images' + result + '\[\/img\]');
ajaxChat.sendMessage();
} else {
alert('An error occurred!');
}
form.reset();
};
// Send data
xhr.send(formData);
}
}
Here is upload.php:
<?php
$valid_file = true;
if($_FILES['photo']['name']) {
//if no errors...
if(!$_FILES['photo']['error']) {
//now is the time to modify the future file name and validate the file
$new_file_name = strtolower($_FILES['photo']['tmp_name']); //rename file
if($_FILES['photo']['size'] > (1024000)) { //can't be larger than 1 MB
$valid_file = false;
}
//if the file has passed the test
if($valid_file) {
//move it to where we want it to be
move_uploaded_file($_FILES['photo']['tmp_name'], '/var/www/html/images'.$new_file_name);
$message = $new_file_name;
exit("$message");
}
}
}
?>
I currently have the multiple image upload disabled, so the "Loop through selected files" only executes once.
The upload worked for a little bit on my PC, but then I tried uploading an image from my phone. When I did so, the entire server (and my browser) crashed, presumably due to an infinite loop somewhere. Every time I close my browser and log back in, or restart the server, or restart my computer, it hangs and eventually crashes again (on my PC or on my phone). I have been unable to find the script that is causing the issue. I get the feeling it's right under my nose. Does anyone see the problem? If you need the HTML form code then I can provide that, but I don't think it's necessary.
I've searched for hours to get a solution for my problem. But I have to ask the community now. I've programmed an ajax file upload system. Here is the Javascript:
var handleUpload = function(event) {
event.preventDefault();
event.stopPropagation();
var fileInput = document.getElementById('fileAvatar');
var data = new FormData();
data.append('ajax', true);
data.append('avatar', fileInput.files[0]);
var request = new XMLHttpRequest();
request.upload.addEventListener('error', function(event) {
alert('Upload Failed');
});
request.addEventListener('readystatechange',function(event) {
if (this.readyState == 4) {
if (this.status == 200) {
var uploaded = this.response.split("|");
// DO SOME ERROR HANDLING IN THIS AREA
if (uploaded[0] == 'upload_success') {
$('.avatarCropImage').attr('src','<?php echo USERFILES;?><?php echo $log_username; ?>/' + uploaded[1]);
$('.cropInput').attr('type',uploaded[2]);
showPopup('cropAvatar');
/************************/
/***** Problem Area *****/
/************************/
} else {
showPopup('errorNotification');
_('popupError').innerHTML = 'Something went wrong. Please try again.';
}
} else {
alert('Error' + this.status);
}
}
});
request.open('POST','<?php echo $url_data; ?>');
request.setRequestHeader('Cashe-Control', 'no-cashe');
request.send(data);
}
window.addEventListener('load', function() {
var submit = document.getElementById('submitAvatar');
submit.addEventListener('click',handleUpload);
});
The file upload works fine and as you can see, after the file was uploaded I push the uploaded image into a popup called cropAvatar.
Then the user has to crop an area to get a thumbnail of his avatar. If he selects an area and clicks on the Crop-Button, the Crop-Function will be run:
function cropImage() {
var top = $('.cropBox').position().top - 3;
var left = $('.cropBox').position().left - 3;
var width = $('.cropBox').width();
var height = $('.cropBox').height();
var src = $('.avatarCropImage').attr('src');
var type = $('.cropInput').attr('type');
var ajax = ajaxObj("POST", "<?php echo $url_data; ?>");
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) == true) {
if (ajax.responseText == "") {
$('.buttonClose').click();
$('.avatarImage').attr('src',src);
$('.cropAvatar').css('display','none');
} else {
alert(ajax.responseText);
showPopup('errorNotification');
_('popupError').innerHTML = 'Something went wrong. Please try again.';
}
}
}
ajax.send("action=avatar&top="+top+"&left="+left+"&width="+width+"&height="+height+"&src="+src+"&type="+type);
}
This also works pretty well. The problem now is that the user can bypass the Crop-Function when he reloads the page. Do you have any solution for that?
I also tried to fix this problem by entering the following code into the Problem Area:
// cropImage() is the Crop-Function
window.unload = cropImage();
Thanks for helping.
Don't save the avatar until the user has done the cropping step.
Leave the file as a dangling temp file until the user has completed the whole upload wizard.
I can come up with a similar scenario:
When you paste a link into a Facebook post, Facebook will give you a thumbnail image for the link. What if you then cancel the post? Where does the thumbnail go, or actually, where has it been since there was no post yet? It's all in a temporary structure until you commit, ie. complete the post.