How to upload canvas image to storage on Laravel - ajax

I have small laravel project that need to upload file from canvas to storage/uploads/imgs. This is my canvas
<body>
<canvas id="canvas"></canvas>
</body>
I may need ajax for client as below
var canvas = document.getElementById('image');
var dataURL = canvas.toDataURL();
$.ajax({
type: "POST",
url: "/route-here",
data: {
imgBase64: dataURL
}
}).done(function(o) {
console.log('saved');
});
But I'm not sure for coding in server(Laravel) side. Any advise or guidance would be greatly appreciated, Thanks.

I dont use Canvas, but do a bit of file uploading... You can use standard php methods for moving files in Laravel... Also, whilst you can definitely use AJAX, you could also accomplish this via a form...
Example of how I handle the upload in my controller:
if ($request->file('image')) {
$asset = $request->file('image')->getClientOriginalName();
$request->file('image')->move(
base_path() . '/storage/app/uploads/imgs/', $asset
);
}
I would also normally, do a check for path (as if your path doesn't exist - it will fail), duplicate file name etc before the ->move method is invoked.
A better way long term is to learn how the Laravel Storage class works - which is less code - but needs "disks" configured correctly as well as including the class in your controller etc.
Hope above helps point you in right direction...

Related

How to delete renamed or non-renamed files in Dropzone.js - simple solution

I was working on this for a full day until I figured out this simple method that I am sharing with yall.
Use this part to listen to a deletion of a thumbnail:
init: function()
{
this.on("removedfile", function(file)
{
var lot = $(file.previewElement).find('[data-dz-name]').text();
$.post("image_delete.php",{name: lot});
});
}
The variable lot gets the name of the image or if you used renameFilename then it gets the new renamed name and with the POST method it is sent to the image_delete.php file that looks like this:
<?php
$tobedeleted = "images/".$_POST['name'];
unlink("$tobedeleted");
?>
I hope this helps a lot of people who struggled with this problem.
Happy coding :)

How to 'POST' a image through xhttp?

I´m trying to do this:
var http = new XMLHttpRequest();
var url = "guardarImg.php";
var params = $('#form').serialize();
http.open("POST", url, true);
http.setRequestHeader("Content-type", "multipart/form-data");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
But is not working, it shows me in my php that 'Image' is not defined, but when I do it through a average Submit it works fine.
All the similar samples I saw work with string data but I need to achieve it with images to make it work later in Intel XDK
What I´m doing wrong?
Can you show me a sample?
Sorry if my question is too basic, I´m a noob with xmlhttp and ajax stuff.
You have the right idea with regard to $("#form").serialize() but for the mess that is (still) AJAX uploads. Yuck (and shame on me for not noting that detail the first time :-( ).
The problem with file uploads via AJAX is (as is often the case), Internet Explorer. Basically, it didn't support the FormData object until IE10 (which means that, if you care about supporting XP users, they'd better be running not-IE). FormData greatly simplifies the process of uploading stuff via AJAX; if you don't have that, here are your options:
Put a little tiny IFRAME on the page and manage that for the actual file upload.
Encode the form data programmatically using something like JSON and send that via jQuery.
Use a nice plugin that wraps this all for you (and uses one or more of these techniques under the covers).
I'm going to assume you don't care about IE8/9 (pretty much everyone else isn't a problem) and give you a FormData solution. Unlike the previous edit, I'm popping in the whole function in here since it's decently informative. This particular solution uploads an entire form, pulling in the existing fields into the FormData object and treating the files specially.
<!-- Many ways to skin this particular feline; I like this one :-) -->
<form onsubmit="return uploadFiles(this)">
<!-- Access from PHP using $_FILES["somefile"]["name"][$idx]... -->
<input type="file" name="somefiles" multiple="1" />
</form>
<script>
// Function to upload a form via FormData, breaking out files and cutting
// any non-named elements. Assumes that there's a #status DIV and the
// URL is hardcoded.
function uploadFiles(frm) {
var formdata = new FormData();
// I'm doing this to separate out the upload content. Note that multiple
// files can be uploaded and will appear as a decently-friendly PHP array
// in $_FILES. Note also that this does handle multiple files properly
// (a default FormData(frm) wouldn't exactly :-( ).
$(frm).find(":input").each(function(idx, ele) {
// This is a file field. Break it out.
if(ele.files) {
for(i=0; i<ele.files.length; i++) {
formdata.append(ele.name + "[" + i + "]", ele.files[i]);
}
// Not a file element, so put in the upload iff there's a name.
} else if(ele.name) {
formdata.append(ele.name, ele.value);
}
});
// Run the AJAX.
$.ajax({
url: "test.php", // Change Me :-)
type: "POST",
data: formdata,
processData: false, // Need these to keep jQuery from messing up your form
contentType: false,
success: function(data) {
$("#status").html(data);
},
error: function(xhr, status, error) {
$("#status").html("Error uploading file(s): " + error);
},
});
return false; // Keep the form from submitting
}
</script>
I have a complete HTML file and corresponding PHP that work at pastebin.
If I were you, I'd actually just use Sebastian's jQuery File Upload if you can. It's got all that modern UI goodness (include progress metering), browser abstraction, and it's MIT licensed to boot. That said, this answer will get you on your way if you just need something to copypasta. Good luck!

Cross Domain Problems when loading OBJ/MTL Files with textures in THREE.JS

I have an OBJ file generated dynamically by a server on a separate domain. It has some materials and texture JPG files.
I load this OBJ file with a simple php proxy (fileProxy.php):
<?php
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Headers: X-Requested-With');
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT'); // http://stackoverflow.com/a/7605119/578667
header('Access-Control-Max-Age: 86400');
//Check if this is an image. if So print coorect header.
if (strpos($_REQUEST['fileToProxy'],'jpg') !== false) {
header('Content-Type: image/jpeg');
}
$proxyFile = (isset($_REQUEST['fileToProxy'])? $_REQUEST['fileToProxy'] : null);
if ( isset($proxyFile)){
// the files sent to us aren't properly url encoded
$proxyFile = str_replace(' ', '+', $proxyFile);
$content = file_get_contents($proxyFile);
print($content);
}
else {
echo "ERROR: no file to proxy";
}
?>
Loading the OBJ files works like a charm
BUT, i cant load the JPG textures embeded in the MTL file. Single colored shaders all work fine, but loading images i get errors.
I get the following error in chrome:
Uncaught SecurityError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': the cross-origin image at http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fil…est-2.compute.amazonaws.com/3DModels/435639/DonutFullBread.jpg&timtest=115 may not be loaded.
The address of the texture file is fed correctly into my proxy:
http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fileToProxy=http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/3DModels/435639/DonutFullBread.jpg&timtest=115
Now after checking my Network monitor, i realise that the Jpg Image is successfully downloaded and the correct CORS headers are all in place. But webgl/three.js still spits out the errors and does not display my model.
SO this seems like a WEBGL bug. But i get security erros in all browsers.
I have tested this on my localhost and on my server. Same problem.
Any solutions?
UPDATE
Here's how i load the OBJ/MTL files with three.js:
(Only cross domain textures fail)
var loader = new THREE.OBJMTLLoader( manager);
///////////////////LOAD MDOEL////////////////////
loader.load( 'http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fileToProxy=' + obj.file, 'http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fileToProxy=' + obj.material, function ( object ) {
//if loaded, do some stuff here.
}
loadedmodel.add(object);
That's all I do really. The Materials and textures are phrased correctly by the loader.
I dont have to set any materials up.
I just want to put this here for other people.
I had a very similar problem when i was trying to load images from static google map images.
So here is what i did
THREE.ImageUtils.crossOrigin = "anonymous";
Just before the actual texure is being loaded.
Now this got it working and i could load the images without a problem.
I know this is old, but I just spent a few hours troubleshooting the same issue, so I thought I'd post an answer here for any future users that run into this. The solution is quite simple, but unfortunately it is not documented anywhere that I could see. I discovered it by pure dumb luck.
var loader = new THREE.OBJMTLLoader( manager);
loader.crossOrigin = ''; // <-- this is all you need to add!
///////////////////LOAD MDOEL////////////////////
loader.load( 'http://obj_url.com', 'http://mtl_url.com', function ( object ) {
//if loaded, do some stuff here.
}
loadedmodel.add(object);
If it's not clear in the code above, the only thing you need to do is to add the line loader.crossOrigin = ''; after declaring the OBJMTLLoader.
I hope this helps someone in the future!
You need to set the crossorigin property explicitly for the image. Copying from one of my own examples:
images[id].image = new Image();
images[id].image.crossOrigin = "anonymous";
images[id].image.onload = function() {/* WebGL texture load of file here */}
images[id].image.src = "http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/fileProxy.php?fileToProxy=http://ec2-54-201-204-177.us-west-2.compute.amazonaws.com/3DModels/435639/DonutFullBread.jpg&timtest=115"
I loaded the image that you have mentioned above, and it works correctly for me in the browser as a texture.
I often joke about my projects blowing up because I forgot a semicolon. Well, this time it is no joke. Someone actually forgot a semicolon in the latest revision of ThreeJS. I dug into MTLLoader.js (which is referenced by OBJMTLLoader.js) and found that this line (near the bottom of the MTLLoader prototype constructor) had a semicolon missing:
materialCreator.crossOrigin = this.crossOrigin
That'll kill any cross-site sharing for all materials. I added the semicolon back in...
materialCreator.crossOrigin = this.crossOrigin;
...and all was well with the world again.

Export Canvas WITH an image AS an image (like PNG or jpg)

I just basically want to get the "http://... .png" or "http://... .jpg" location of my canvas as an image.
I have already tried toDataURL() but it is not working. Especially if I loaded an image within the canvas.
Here is my code: (btw, I'm using jQuery here)
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
var canvas = $("#canvas");
var ctx = canvas.get(0).getContext("2d");
var image1 = new Image();
image1.src = "http://www.helpinghomelesscats.com/images/cat1.jpg"
$(image1).load(function(){
ctx.drawImage(image1,0,0,200,200);
});
});
</script>
with my html/body having only this:
<canvas id="canvas" width="500" height="400"></canvas>
now, if you try that, that works fine. it shows that cat.
but when i add that toDataURL into my script, it just doesn't happen.
var dataImg = canvas.get(0).toDataURL();
i load this dataImg variable into another click-redirect function to test it, hoping it would redirect to the page using the base64 url it contains, but it just doesn't work:
$("#canvas").click(function(){
document.location = dataImg;
});
it brings me to a blank page? what am i missing here?
thank you very much!
Do you own http://www.helpinghomelesscats.com or is your code hosted directly on that site? If not you won't be able to do this due to cross site origin policies. The best way would be to have some server side code grab the image and then serve it locally on your domain.
If you do own helpinghomelesscats.com this should work, as tested here
Live Demo
Click the canvas and view the log in order to see the response.

Sending data from a file on iPad to a php file on server via AJAX

I'm trying to upload data captured in a local html file on an iPad and save it to server.
I found this: Sending data to an external file via Ajax
So as far as I can understand, there is no way to send the info doing something like this:
ajax.open("POST",'http://www.misite.com/canvas/testSave.php',true);
from a html on the iPad, I'm right?
So I just want to know if anyone knows a trick to do this. Thanks!
After a couple of weeks this is what I could achieved.
1.- The function that sends the data (an image generated from a canvas):
function sendImageData()
{
var filename = $("#filename").val().trim();
if(filename == ''){
alert("File name is needed");
return;
}
var uploadCanvas = $("#uploadCanvas");
var canvasData = uploadCanvas[0].toDataURL("image/png");
var debugConsole= $("#debugConsole");
debugConsole.val(canvasData);
$.ajax({
type: 'POST',
url: "http://yourremoteserver.com/canvas/save.php",
data: {
canvasData:canvasData,
filename:filename
}
}).done(function() {
alert("saved: " + filename + ".png");// THIS IS NOT WORKING YET.
}
);
}
2.- The PHP that receives and saves the data:
<?php
$imagen = $_POST['canvasData'];
$filename = $_POST['filename'];
if (isset($imagen)){
$imageData=$imagen;
$filteredData=substr($imageData, strpos($imageData, ",")+1);
$unencodedData=base64_decode($filteredData);
$fp = fopen( $filename.'.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
If anyone can help me with the .done function to work (remember, the html file is in an ipad and the php on a server) let me know. Cheers.
I have used Plupload for this purpose. It automagically switches between flash, silverlight, and html5 so it should work on just about any browser (including the safari on the iPad). Basically, it uploads a file to a processing script with some generated id (it generates it for you). Then, you can poll another page to get the uploaded data once it is finished uploading.
EDIT: Re-reading your post I am not sure how pertinent this is since it requires the user to select a file and I'm not sure that's what you are getting at exactly.

Resources